zoukankan      html  css  js  c++  java
  • HGOI20180817 (NOIP模拟Day1 task)

    HGOI自测

    初测:150=80+20+50 rank1~rank3(并列3个rank1,所以我是rank3 qwq)

    今日分突然想简约

     CF359A Table

    https://www.luogu.org/problemnew/show/CF359A

    题目描述

    Simon has a rectangular table consisting of nn rows and mm columns. Simon numbered the rows of the table from top to bottom starting from one and the columns — from left to right starting from one. We'll represent the cell on the xx -th row and the yy -th column as a pair of numbers (x,y)(x,y) . The table corners are cells: (1,1)(1,1) , (n,1)(n,1) , (1,m)(1,m) , (n,m)(n,m) .

    Simon thinks that some cells in this table are good. Besides, it's known that no good cell is the corner of the table.

    Initially, all cells of the table are colorless. Simon wants to color all cells of his table. In one move, he can choose any good cell of table (x_{1},y_{1})(x1,y1) , an arbitrary corner of the table (x_{2},y_{2})(x2,y2) and color all cells of the table (p,q)(p,q) , which meet both inequations: min(x_{1},x_{2})<=p<=max(x_{1},x_{2})min(x1,x2)<=p<=max(x1,x2) , min(y_{1},y_{2})<=q<=max(y_{1},y_{2})min(y1,y2)<=q<=max(y1,y2) .

    Help Simon! Find the minimum number of operations needed to color all cells of the table. Note that you can color one cell multiple times.

    输入输出格式

    输入格式:

    The first line contains exactly two integers nn , mm ( 3<=n,m<=503<=n,m<=50 ).

    Next nn lines contain the description of the table cells. Specifically, the ii -th line contains mm space-separated integers a_{i1},a_{i2},...,a_{im}ai1,ai2,...,aim . If a_{ij}aij equals zero, then cell (i,j)(i,j) isn't good. Otherwise a_{ij}aij equals one. It is guaranteed that at least one cell is good. It is guaranteed that no good cell is a corner.

    输出格式:

    Print a single number — the minimum number of operations Simon needs to carry out his idea.

    输入输出样例

    输入样例#1:
    3 3
    0 0 0
    0 1 0
    0 0 0
    
    输出样例#1: 
    4
    
    输入样例#2: 
    4 3
    0 0 0
    0 0 1
    1 0 0
    0 0 0
    
    输出样例#2: 
    2
    

    说明

    In the first sample, the sequence of operations can be like this:

    - For the first time you need to choose cell (2,2)(2,2) and corner (1,1)(1,1) .

    • For the second time you need to choose cell (2,2)(2,2) and corner (3,3)(3,3) .
    • For the third time you need to choose cell (2,2)(2,2) and corner (3,1)(3,1) .
    • For the fourth time you need to choose cell (2,2)(2,2) and corner (1,3)(1,3) .

    In the second sample the sequence of operations can be like this:

    - For the first time you need to choose cell (3,1)(3,1) and corner (4,3)(4,3) .

    • For the second time you need to choose cell (2,3)(2,3) and corner (1,1)(1,1) .

    简约题解: 在边界就是2,不在边界就是4,说完了

    考场上为甚么是80pts呢?

    # include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,m; scanf("%d%d",&n,&m);
        int t; bool f1=false;
        for (int i=1;i<=n;i++)
         for (int j=1;j<=n;j++) {
              scanf("%d",&t); 
            if (t==1)  if (i==1||i==n||j==1||j==n) f1=true;
          }
          if (f1) printf("2
    "); else printf("4
    ");
        return 0;
    }

    手贱qwq

    AC代码:

    # include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,m; scanf("%d%d",&n,&m);
        int t; bool f1=false;
        for (int i=1;i<=n;i++)
         for (int j=1;j<=m;j++) {
              scanf("%d",&t); 
            if (t==1)  if (i==1||i==n||j==1||j==m) f1=true;
          }
          if (f1) printf("2
    "); else printf("4
    ");
        return 0;
    }

    CF17C Balance

    https://www.luogu.org/problemnew/show/CF17C

    题意翻译

    【题目描述】 一个仅由a,b,c三种字符组成的字符串,可以对其进行如下两种操作:

    1. 选择两个相邻字符,将第一个字符替换成第二个。
    2. 选择两个相邻字符,将第二个字符替换成第一个。 这样,通过任意多次的操作,可以得到许多不同的串,为了追求字符的平衡, 我们要求a,b,c三种字符在字符串中出现的次数两两之差都不能大于1。

    你的任 务是,统计给定字符串通过任意多次的操作,能够得到的不同的平衡串的个数。

    【输入格式】

    输入文件包含2行。 第一行包含1个正整数n,表示字符串长度。 第二行包含1个长度为n的字符串。

    【输出格式】

    输出共1行,包含1个正整数,表示能够得到的平衡串的数量。由于答案可 能很大,因此输出时要对51123987取模。

    题目描述

    Nick likes strings very much, he likes to rotate them, sort them, rearrange characters within a string... Once he wrote a random string of characters a, b, c on a piece of paper and began to perform the following operations:

    • to take two adjacent characters and replace the second character with the first one,
    • to take two adjacent characters and replace the first character with the second one

    To understand these actions better, let's take a look at a string «abc». All of the following strings can be obtained by performing one of the described operations on «abc»: «bbc», «abb», «acc». Let's denote the frequency of a character for each of the characters a, b and c as the number of occurrences of this character in the string. For example, for string «abc»: | aa | = 1, | bb | = 1, | cc | = 1, and for string «bbc»: | aa | = 0, | bb | = 2, | cc | = 1.

    While performing the described operations, Nick sometimes got balanced strings. Let's say that a string is balanced, if the frequencies of each character differ by at most 1. That is -1<=|a|-|b|<=11<=ab<=1 , -1<=|a|-|c|<=11<=ac<=1 и -1<=|b|-|c|<=11<=bc<=1 .

    Would you help Nick find the number of different balanced strings that can be obtained by performing the operations described above, perhaps multiple times, on the given string ss . This number should be calculated modulo 5112398751123987 .

    输入输出格式

    输入格式:

    The first line contains integer nn ( 1<=n<=150 ) — the length of the given string s . Next line contains the given string s . The initial string can be balanced as well, in this case it should be counted too. The given string ss consists only of characters a, b and c.

    输出格式:

    Output the only number — the number of different balanced strings that can be obtained by performing the described operations, perhaps multiple times, on the given string ss , modulo 51123987

    输入输出样例

    输入样例#1: 
    4
    abca
    
    输出样例#1: 
    7
    
    输入样例#2: 
    4
    abbc
    
    输出样例#2: 
    3
    
    输入样例#3: 
    2
    ab
    
    输出样例#3: 
    1
    

    说明

    In the first sample it is possible to get 5151 different strings through the described operations, but only 77 of them are balanced: «abca», «bbca», «bcca», «bcaa», «abcc», «abbc», «aabc». In the second sample: «abbc», «aabc», «abcc». In the third sample there is only one balanced string — «ab» itself.

    20pts code1:

    # include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mo=51123987,mod=19260817,e=7;
    struct Node{
        string s;
        int a,b,c;
    };
    queue<Node>q;
    string s;
    Node N,u,v;
    int ans=0,n;
    ll HH;
    map<ll,bool>mp;
    ll hash(string s)
    {
        ll sum=0ll;
        for (int i=0;i<s.length();i++)
         sum=(sum*e%mod+s[i]%mod)%mod;
        return sum;
    }
    void bfs()
    {
        int a=0,b=0,c=0;
        for (int i=0;i<s.length();i++)
         if (s[i]=='a') a++;
         else if (s[i]=='b') b++;
         else if (s[i]=='c') c++;
        N.s=s;N.a=a;N.b=b;N.c=c;
        mp.clear(); mp[hash(s)]=1;
        q.push(N);
        while (! q.empty()) {
            u=q.front();q.pop();
            if (abs(u.a-u.b)<=1&&abs(u.b-u.c)<=1&&abs(u.a-u.c)<=1) ans=(ans+1)%mo;
            int len=s.length();
            for (int i=0;i<len;i++) {
                if (i==0) {
                    v=u;
                    if (v.s[0]=='a') v.a--;
                    else if (v.s[0]=='b') v.b--;
                    else v.c--;
                    if (v.s[1]=='a') v.a++;
                    else if (v.s[1]=='b') v.b++;
                    else v.c++;
                    v.s[0]=v.s[1];
                    HH=hash(v.s);
                    if (mp.count(HH)!=0) continue;
                    mp[HH]=true;
                    q.push(v);
                      continue;
                }
                if (i==len-1){
                    v=u;
                    if (v.s[len-1]=='a') v.a--;
                    else if (v.s[len-1]=='b') v.b--;
                    else v.c--;
                    if (v.s[len-2]=='a') v.a++;
                    else if (v.s[len-2]=='b') v.b++;
                    else v.c++;
                    v.s[len-1]=v.s[len-2];
                    HH=hash(v.s);
                    if (mp.count(HH)!=0) continue;
                    mp[HH]=true;
                    q.push(v);
                    continue;
                }
                v=u;
                if (v.s[i]=='a') v.a--;
                else if (v.s[i]=='b') v.b--;
                else v.c--;
                if (v.s[i-1]=='a') v.a++;
                else if (v.s[i-1]=='b') v.b++;
                else v.c++;
                v.s[i]=v.s[i-1];
                HH=hash(v.s);
                if (mp.count(HH)==0) {
                    mp[HH]=true;
                    q.push(v);
                }        
                v=u;    
                if (v.s[i]=='a') v.a--;
                else if (v.s[i]=='b') v.b--;
                else v.c--;
                if (v.s[i+1]=='a') v.a++;
                else if (v.s[i+1]=='b') v.b++;
                else v.c++;
                v.s[i]=v.s[i+1];
                HH=hash(v.s);
                if (mp.count(HH)==0) {
                    mp[HH]=true;
                    q.push(v);
                }    
            }
        } 
    }
    int main()
    {
        freopen("balance.in","r",stdin);
        freopen("balance.out","w",stdout);
        scanf("%d
    ",&n);
        cin>>s;
        ans=0;
        bfs();
        printf("%d
    ",ans%mo);
        return 0;
    }

    20pts code2:(莫名心酸)

    # include <bits/stdc++.h>
    using namespace std;
    int main()
    {
        freopen("balance.in","r",stdin);
        freopen("balance.out","w",stdout);
        printf("0
    ");
        return 0;
    }

    正解是:dp

    先将字符串压缩(连续)

    aabbaacc就是这样abac显然所有满足题意的字符串都是在abac上拓展出来的,

    比如说abbbbacc等等

    设dp[i][a][b][c]是最后一个选的字符在原串的第i位,用了a个"a" b个"b" c个"c";

    注意到第i个字符只能从前往后选(背包)这样就避免后效性

    dp[i][a][b][c]对dp[next[i][0]][a+1][b][c]

    dp[i][a][b][c]对dp[next[i][1]][a][b+1][c]

    dp[i][a][b][c]对dp[next[i][2]][a][b][c+1]

    有影响,(累加)

    其中next[i][0-2]表示在原串i(含)后第一次出现a,b,c的位置如果没有出现是-1

    0代表a,1代表b,2代表c

    方程:

    dp[next[i][0]][a+1][b][c]=dp[i][a][b][c]+dp[next[i][0]][a+1][b][c]

    dp[next[i][1]][a][b+1][c]=dp[i][a][b][c]+dp[next[i][1]][a][b+1][c]

    dp[next[i][2]][a][b][c+1]=dp[i][a][b][c]+dp[next[i][2]][a][b][c+1]

    初值:dp[1][0][0][0]=1;

    100pts:

    # include <bits/stdc++.h>
    using namespace std;
    const int mo=51123987;
    char s[152];
    int dp[152][53][53][53];
    int next[155][3];
    int main()
    {
        int n; scanf("%d",&n);
        scanf("%s",s+1);
        for (int i=1;i<=n;i++) {
            int j;
            for (j=i;j<=n;j++) if (s[j]=='a') break;
            if (j>n) next[i][0]=-1;
            else next[i][0]=j;
        }
        for (int i=1;i<=n;i++) {
            int j;
            for (j=i;j<=n;j++) if (s[j]=='b') break;
            if (j>n) next[i][1]=-1;
            else next[i][1]=j;
        }
        for (int i=1;i<=n;i++) {
            int j;
            for (j=i;j<=n;j++) if (s[j]=='c') break;
            if (j>n) next[i][2]=-1;
            else next[i][2]=j;
        }
        int ans=0ll;
        dp[1][0][0][0]=1;
        for (int i=1;i<=n;i++)
        for (int a=0;a<=n/3+1;a++)
        for (int b=0;b<=n/3+1;b++)
        for (int c=0;c<=n/3+1;c++)
            {
                if (a+b+c==n&&abs(a-b)<=1&&abs(b-c)<=1&&abs(c-a)<=1) {
                    ans=(dp[i][a][b][c]+ans)%mo;
                    continue;
                }
                if (next[i][0]>=0)  dp[next[i][0]][a+1][b][c]=(dp[next[i][0]][a+1][b][c]+dp[i][a][b][c])%mo;
                if (next[i][1]>=0)  dp[next[i][1]][a][b+1][c]=(dp[next[i][1]][a][b+1][c]+dp[i][a][b][c])%mo;
                if (next[i][2]>=0)  dp[next[i][2]][a][b][c+1]=(dp[next[i][2]][a][b][c+1]+dp[i][a][b][c])%mo;
            }
        printf("%d
    ",ans);
        return 0;
    }

    CF19E Fairy

    https://www.luogu.org/problemnew/show/CF19E

    题意翻译

    题目描述

    很久很久以前,有一个仙女叫做A。有一天一个少年B找到她,并且请求她预测他的未来。仙女看着她的水晶球,说这位少年不久将遇见世界上最美丽的公主,并且将迎娶她为妻。然后仙女在一张纸上画了n个点,并把它们分为几个板块,每个板块以一些点为始,另一些点为终。画完这幅画,仙女要求少年擦掉之上的一个板块。然后她尝试给每个点画上红色或蓝色,让纸上没有板块有和它的结尾颜色一样的点。如果她能做到,这个预言将会成真。B想邂逅世界上最美丽的公主,所以他想要你帮助他。找到所有能帮助他邂逅公主的板块。

    输入输出格式:

    输入格式:

    输入文件的第一行有两个整数:n——点数;m:板块个数。

    接下来的m行有板块的描述。每一个描述有两个整数,用空格隔开——v,u——各点的编号(index),由此板块连接。没有板块在描述中会被描述两次。

    输出格式:

    输出文件的第一行输出数字k——答案中板块的数量。输出文件的第二行输出k个数字,以空格隔开————每个板块的编号,升序排列。每个编号只应被输出一次。板块从1开始编号,以输入的顺序为序。

    感谢@qwerta 提供的翻译

    题目描述

    Once upon a time there lived a good fairy A. One day a fine young man B came to her and asked to predict his future. The fairy looked into her magic ball and said that soon the fine young man will meet the most beautiful princess ever and will marry her. Then she drew on a sheet of paper nn points and joined some of them with segments, each of the segments starts in some point and ends in some other point. Having drawn that picture, she asked the young man to erase one of the segments from the sheet. Then she tries to colour each point red or blue so, that there is no segment having points of the same colour as its ends. If she manages to do so, the prediction will come true. B wants to meet the most beautiful princess, that's why he asks you to help him. Find all the segments that will help him to meet the princess.

    输入输出格式

    输入格式:

    The first input line contains two integer numbers: nn — amount of the drawn points and mm — amount of the drawn segments ( 1<=n<=10^{4},0<=m<=10^{4}1<=n<=104,0<=m<=104 ). The following mm lines contain the descriptions of the segments. Each description contains two different space-separated integer numbers vv , uu ( 1<=v<=n,1<=u<=n1<=v<=n,1<=u<=n ) — indexes of the points, joined by this segment. No segment is met in the description twice.

    输出格式:

    In the first line output number kk — amount of the segments in the answer. In the second line output kkspace-separated numbers — indexes of these segments in ascending order. Each index should be output only once. Segments are numbered from 1 in the input order.

    输入输出样例

    输入样例#1: 
    4 4
    1 2
    1 3
    2 4
    3 4
    
    输出样例#1: 
    4
    1 2 3 4 
    输入样例#2: 
    4 5
    1 2
    2 3
    3 4
    4 1
    1 3
    
    输出样例#2: 
    1
    5 

    考场上打了把暴力 50pts,就是模拟染色:
    # include <bits/stdc++.h>
    using namespace std;
    const int MAXN=1000010;
    struct rec{
        int pre,to;
    }a[2*MAXN];
    bool flag,vis[MAXN];
    int ans[MAXN],tot=0,head[MAXN],col[MAXN],n,m,now;
    inline int read()
    {
        int X=0,w=0; char c=0;
        while(c<'0'||c>'9') {w|=c=='-';c=getchar();}
        while(c>='0'&&c<='9') X=(X<<3)+(X<<1)+(c^48),c=getchar();
        return w?-X:X;
    }
    inline void adde(int u,int v)
    {
        a[++tot].pre=head[u];
        a[tot].to=v;
        head[u]=tot;
    }
    inline void dfs(int u)
    {
        vis[u]=true;
        for (register int i=head[u];i!=0;i=a[i].pre)
        {
            if (i==now||i==now-1) continue;
            int v=a[i].to; 
            if (vis[v]){
                if (col[u]==col[v]) {
                    flag=false; return;
                } else continue;
            }
            if (col[u]==0) col[v]=1; 
            else col[v]=0;
            dfs(v);
        }
    }
    int main()
    {
        freopen("fairy.in","r",stdin);
        freopen("fairy.out","w",stdout);
        n=read();m=read();
        int u,v;
        for (register int i=1;i<=m;i++) {
            u=read();v=read();
            adde(u,v); adde(v,u);
        }
        for (register int i=1;i<=tot;i++) {
            if (i%2==1) continue;
            memset(vis,false,sizeof(vis));
            memset(col,-1,sizeof(col));
            now=i;
            flag=true;
            for (register int j=1;j<=n;j++)
             if (vis[j]==false) {
                  col[j]=1; dfs(j);
                 if (!flag) break;
             }
            if (flag) ans[++ans[0]]=i/2;
        }
        printf("%d
    ",ans[0]);
        for (register int i=1;i<=ans[0];i++) printf("%d ",ans[i]);
        printf("
    ");
        return 0;
    }

    std:

    题意

    给一张无向图,求删掉哪几条边可以变成二分图;

    方法

    如果没有奇环,任何边都可以删;

    如果只有一个奇环,那么奇环上的边都可以被删;

    如果多于1个,必须选在所有奇环且不在偶环上的点;

    根据树上差分的方法,应该在两个端点+1,LCA-2,而DFS树无横叉边,所以LCA就是深度较浅的点,将它+1-2即可;

    统计tag==n的点,其父边就是ans;

    100pts:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<list>
    #include<queue>
    #include<stack>
    #include<bitset>
    #include<deque>
    using namespace std;
    #define ll long long
    #define inf 0x3f3f3f3f
    #define ri register int
    #define il inline
    #define fi first
    #define se second
    #define mp make_pair
    #define pi pair<int,int>
    #define mem0(x) memset((x),0,sizeof (x))
    #define mem1(x) memset((x),0x3f,sizeof (x))
    #define gc getchar
    #define pb push_back
    template<class T>void in(T &x)
    {
        x = 0; bool f = 0; char c = gc();
        while (c < '0' || c > '9') {if (c == '-') f = 1; c = gc();}
        while ('0' <= c && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = gc();}
        if (f) x = -x;
    }
    #undef gc
    void out(int x) {
        if (x < 0) putchar('-'), x = -x;
        if (x > 9) out(x / 10);
        putchar(x % 10 + '0');
    }
    #define N 10010
    #define M N<<2
    int n, m;
    int v[M], u[M], nx[M], k[M];
    int cnt = 1, head[N];
    il void add(int uu, int vv) {
        u[++cnt] = uu, v[cnt] = vv, nx[cnt] = head[uu];
        head[uu] = cnt;
        k[cnt] = (cnt >> 1);
    }
    int dep[N];
    bool vis[N];
    int tag[N];
    int zt;
    vector<int>ans;
    int lst;
    void dfs(int x, int f, int d) {
        //printf("V %d
    ",x);
        dep[x] = d;
        vis[x] = 1;
        for (ri i = head[x]; i; i = nx[i]) {
            if (i == f) continue;
            if (!vis[v[i]]) {
                dfs(v[i], i ^ 1, d + 1);
            }
            else {
                if (dep[v[i]] < dep[x]) continue;
                if ((dep[v[i]] - dep[x] + 1) & 1) {
                    tag[x]--;  // in fact +1 -2
                    tag[v[i]]++;
                    zt++;
                    lst=k[i];
                }
                else {
                    tag[x]++;
                    tag[v[i]]--;
                }
            }
        }
    }
    int dfs2(int x, int f) {
        vis[x] = 1;
        int res = tag[x];
        for (ri i = head[x]; i; i = nx[i]) {
            if (vis[v[i]]) continue;
            res += dfs2(v[i], i);
        }
        if (res == zt) ans.pb(k[f]);
        //printf("T %d %d %d
    ",x,res,tag[x]);
        return res;
    }
    signed main() {
        in(n), in(m);
        for (ri i = 1, a, b; i <= m; ++i) {
            in(a), in(b);
            add(a, b);
            add(b, a);
        }
        for (ri i = 1; i <= n; ++i) {
            if (!vis[i]) dfs(i, 0, 0);
        }
        if (zt == 0) {
            //cout << "A";
            printf("%d
    ", m);
            for (ri i = 1; i <= m; ++i) printf("%d ", i);
            return 0;
        }
        if(zt==1) ans.pb(lst);
        //cout<<zt;
        mem0(vis);
        for (ri i = 1; i <= n; ++i) {
            if (!vis[i]) dfs2(i, 0);
        }
        sort(ans.begin(), ans.end());
        printf("%d
    ", ans.size());
        for (ri i = 0; i < ans.size(); ++i) {
            printf("%d ", ans[i]);
        }
        return 0;
    }
     
  • 相关阅读:
    Build a pile of Cubes
    一键升级所有pip过期库
    AWGN
    调制详解——待完善
    BASK、BFSK、BPSK调制方法的Matlab程序实现
    tomcat运行问题解决方法
    ehcache简单使用
    MySQL 数据库中用户表中口令登陆设置
    和自己赛跑的人
    中文词频统计
  • 原文地址:https://www.cnblogs.com/ljc20020730/p/9493627.html
Copyright © 2011-2022 走看看