zoukankan      html  css  js  c++  java
  • 2018 icpc 青岛

    https://zoj.pintia.cn/contests/91827364639/problems

    C

    要把这两个二进制串变为相同,需要先看哪些位置不同,设为数组c,某位为1则两位不同。

    分1形成两段、四段或者更多段来考虑。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <map>
    #define ll long long
    #define ld double
    #define lson rt << 1, l, m
    #define pi acos(-1)
    #define rson rt << 1 | 1, m + 1, r
    #define fo(i, l, r) for (long long i = l; i <= r; i++)
    #define fd(i, l, r) for (long long i = r; i >= l; i--)
    #define mem(x) memset(x, 0, sizeof(x))
    #define eps 1e-10
    using namespace std;
    const ll maxn = 1000050;
    const ll mod = 998244353;
    ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while (!(ch >= '0' && ch <= '9'))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        };
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + (ch - '0');
            ch = getchar();
        };
        return x * f;
    }
    int n,m;
    char s[maxn],t[maxn];
    int pt[10];
    ll ans;
    int main()
    {
    
        int T;
        T = read();
        int tt = 0;
        while (T--)
        {
            ans=0;
            n=read();
            scanf("%s",s+1);
            scanf("%s",t+1);
            fo(i,1,n){
                s[i]-='0';
                t[i]-='0';
                s[i] ^= t[i];
            }
            int cnt = 0;
            fo(i,1,n){
                if(s[i]&&!s[i-1]){
                    pt[++cnt]=i;
                }
                if(s[i]&&!s[i+1]){
                    pt[++cnt]=i;
                }
                if(cnt>4)break;
            }
            if(cnt>4){
                printf("0
    ");
                continue;
            }
            if(cnt==0){
                ans=(ll)n*(n+1)/2;
            }
            if(cnt==2){
                ans=n+n-2;
            }
            if(cnt==4){
                ans=6;
            }
            printf("%d
    ",ans);
    
        }
    
        return 0;
    }

    M

    递归,碰到循环节就停止。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <map>
    #define ll long long
    #define ld double
    #define lson rt << 1, l, m
    #define pi acos(-1)
    #define rson rt << 1 | 1, m + 1, r
    #define fo(i, l, r) for (long long i = l; i <= r; i++)
    #define fd(i, l, r) for (long long i = r; i >= l; i--)
    #define mem(x) memset(x, 0, sizeof(x))
    #define eps 1e-10
    using namespace std;
    const ll maxn = 1050;
    const ll mod = 998244353;
    ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while (!(ch >= '0' && ch <= '9'))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        };
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + (ch - '0');
            ch = getchar();
        };
        return x * f;
    }
    ll x,k;
    ll f[10] = {1,0,0,0,1,0,1,0,2,1};
    ll g(int d,ll x){
        if(d==0) return x;
        if(x==1||x==0){
            return x^(d&1);
        }
        ll ret = 0;
        while(x){
            ret += f[x%10];
            x /= 10;
        }
        return g(d-1,ret);
    }
    int main()
    {
    
        int T;
        T = read();
        int tt = 0;
        while (T--)
        {
            x=read();k=read();
            printf("%lld
    ",g(k,x));   
        }
        return 0;
    }

    J

    正好买m本书,还要带的钱最多。

    考虑到,如果跳过若干本书,买一本,那把后一本书换成一开始跳过的书,答案会增加。

    即,不存在这样的情况,买的书肯定是从1开始到m。

    这个时候答案依然可能增加,要保证之后买不了书,就是加上之后价格最小的那本书-1

    再判断一些特殊情况就可以。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <map>
    #define ll long long
    #define ld double
    #define lson rt << 1, l, m
    #define pi acos(-1)
    #define rson rt << 1 | 1, m + 1, r
    #define fo(i, l, r) for (long long i = l; i <= r; i++)
    #define fd(i, l, r) for (long long i = r; i >= l; i--)
    #define mem(x) memset(x, 0, sizeof(x))
    #define eps 1e-10
    using namespace std;
    const ll maxn = 100050;
    const ll mod = 998244353;
    ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while (!(ch >= '0' && ch <= '9'))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        };
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + (ch - '0');
            ch = getchar();
        };
        return x * f;
    }
    int n,m;
    ll a[maxn],ans;
    int main()
    {
    
        int T;
        T = read();
        int tt = 0;
        while (T--)
        {
            ans=0;
            n=read();m=read();
            fo(i,1,n){
                a[i]=read();
                if(!a[i]){
                    i--;
                    n--;
                    m--;
                }
            }
            if(m<0||m>n){
                printf("Impossible
    ");
                continue;
            }
            if(m==n){
                printf("Richman
    ");
                continue;
            }
            fo(i,1,m){
                ans += a[i];
            }
            ll mn = 1e10;
            fo(i,m+1,n){
                mn = min(mn,a[i]);
            }
            mn--;
            ans+=mn;
            printf("%lld
    ",ans);
        }
    
        return 0;
    }

    E

    试着将操作进行分解,前进n次,倒退n次,把这些操作全部换成前进1次,倒退1次的操作,答案不会变劣。

    首先二分,检验的时候,不断往前走,如果某个时刻发现前一个点不能满足要求,就在这两个点之间反复的跳,注意考虑最后一个点的情况。

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <map>
    #define ll long long
    #define ld double
    #define lson rt << 1, l, m
    #define pi acos(-1)
    #define rson rt << 1 | 1, m + 1, r
    #define fo(i, l, r) for (long long i = l; i <= r; i++)
    #define fd(i, l, r) for (long long i = r; i >= l; i--)
    #define mem(x) memset(x, 0, sizeof(x))
    #define eps 1e-10
    using namespace std;
    const ll maxn = 100050;
    const ll mod = 998244353;
    ll read()
    {
        ll x = 0, f = 1;
        char ch = getchar();
        while (!(ch >= '0' && ch <= '9'))
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        };
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + (ch - '0');
            ch = getchar();
        };
        return x * f;
    }
    ll a[maxn],b[maxn],c[maxn];
    ll n,m,mx;
    bool check(ll t){
        int nown = n;
        fo(i,1,n){
            b[i]=t/a[i];
            if(b[i]*a[i]<t)b[i]++;
        }
        b[n+1]=0;
        while(nown>=1&&b[nown]==0)nown--;
        fo(i,1,nown+1){
            if(i<=n)c[i]=1;
            else c[i]=0;
            if(b[i-1]>c[i-1]){
                c[i] += b[i-1]-c[i-1];
                c[i-1]=b[i-1];
            }
            if(i==n&&c[i]>b[i])c[i]--;
    
        }
        ll ret = 0;
        fo(i,1,nown+1){
            ret += c[i];
            if(ret > m) return false;
        }
        return true;
    }
    int main()
    {
    
        int T;
        T = read();
        int tt = 0;
        while (T--)
        {
            n=read();m=read();
            mx=0;
            fo(i,1,n){
                a[i]=read();
                mx=max(mx,a[i]);
            }
            ll lp = 0,rp = mx*m,mid,ans=0;
            while(lp<=rp){
                mid = (lp + rp) >> 1;
                if(check(mid)){
                    ans = mid;
                    lp = mid + 1;
                }else{
                    rp = mid - 1;
                }
            }
            printf("%lld
    ",ans);
        }
    
        return 0;
    }

    F

    首先,n个人最多打n-1轮,奇数个人不能打。

    2、4个人都能打,然后发现6个人连两轮都打不了。

    一开始是 2 1 4 3 6 5,假如说之后1个3打,按照只能要求1 2 3 4之间有比赛,5还是只能跟6打,因为第二轮与人的序号无关,这时候怎么调整都是徒劳。

    人数是2^n的时候比较好安排,轮换一下就可以。

    人数不是2^n的时候,还是按照2^n的情况排个表,因为之前就是保证字典序最小,所以编号大的都尽量出现在后面,如果这个时候表中出现了不得不跟一个不存在的大号打的情况,这个时候就安排不了了。

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include <set>
    #include <queue>
    #define ll long long
    #define ld long double
    #define lson l,m,rt<<1
    #define pi acos(-1)
    #define rson m+1,r,rt<<1|1
    #define fo(i,l,r) for(int i = l;i <= r;i++)
    #define fd(i,l,r) for(int i = r;i >= l;i--)
    #define mem(x) memset(x,0,sizeof(x))
    #define eps 3e-11
    using namespace std;
    const int maxn = 200050;
    const ll inf = 1e9;
    const ll mod = 998244353;
    ll read() {
        ll x=0,f=1;
        char ch=getchar();
        while(!(ch>='0'&&ch<='9')) {
            if(ch=='-')f=-1;
            ch=getchar();
        };
        while(ch>='0'&&ch<='9') {
            x=x*10+(ch-'0');
            ch=getchar();
        };
        return x*f;
    }
    int n,k;
    int a[2050][2050];
    int main() {
        a[1][1]=a[2][2]=1;
        a[1][2]=a[2][1]=2;
        for(int t = 2;t <= 1024;t <<= 1){
            fo(i,1,t){
                fo(j,1,t){
                    a[t+i][t+j] = a[i][j];
                    a[t+i][j] = a[i][t+j] = a[i][j] + t;
                }
            }
        }
        int T=read();
        while(T--){
            n=read();k=read();
            if((n&1)||k>=n){
                puts("Impossible");
                continue;
            }
            bool flag = false;
            fo(i,1,k){
                fo(j,1,n){
                    if(a[i+1][j] > n)flag=true;
                }
            }
            if(flag){
                puts("Impossible");
                continue;
            }
            fo(i,1,k){
                fo(j,1,n){
                    printf("%d",a[i+1][j]);
                    putchar(j==n?'
    ':' ');
                }
            }
        }
        return 0;
    }

    D

    枚举两个数的第一位,之后所有的位都确定了。

    注意两位数不能有前导零,每一位的范围不能超。

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include <set>
    #include <queue>
    #define ll long long
    #define ld long double
    #define lson l,m,rt<<1
    #define pi acos(-1)
    #define rson m+1,r,rt<<1|1
    #define fo(i,l,r) for(int i = l;i <= r;i++)
    #define fd(i,l,r) for(int i = r;i >= l;i--)
    #define mem(x) memset(x,0,sizeof(x))
    #define eps 3e-11
    using namespace std;
    const int maxn = 400050;
    const ll inf = 1e9;
    const ll mod = 998244353;
    ll read() {
        ll x=0,f=1;
        char ch=getchar();
        while(!(ch>='0'&&ch<='9')) {
            if(ch=='-')f=-1;
            ch=getchar();
        };
        while(ch>='0'&&ch<='9') {
            x=x*10+(ch-'0');
            ch=getchar();
        };
        return x*f;
    }
    ll n,m,len;
    char s[maxn];
    int a[maxn],b[maxn];
    bool flag;
    inline int check(int u,int v,int t){
        if(a[u]*b[v]==s[t])return 1;
        if(t<len&&s[t]&&(s[t]*10+s[t+1])==a[u]*b[v]) return 2;
        return 0;
    }
    inline int dv(int v,int t){
        if(s[t]%v==0) return s[t]/v;
        if(t<len&&(s[t]*10+s[t+1])%v==0) return (s[t]*10+s[t+1])/v;
        return -1;
    }
    bool check(int st){
        int t = st,u=1,v=1,sgn;
        while(t<=len){
            v++;
            if(v>m){
                v=1;
                u++;
            }
            if(u>n)break;
            if(u==1){
                b[v]=dv(a[u],t);
                if(b[v]==-1||b[v]>=10)return false;
            }else if(v==1){
                a[u] = dv(b[v],t);
                if(a[u]==-1||a[u]>=10)return false;
            }else{
                sgn=check(u,v,t);
                if(!sgn)return false;
            }
            t++;
            if(a[u]*b[v]>=10)t++;
        }
        return u==n&&v==m&&t==len+1;
    }
    bool gao(){
        int sgn;
        fo(i,1,9){
            fo(j,1,9){
               a[1]=i;b[1]=j;
               sgn=check(1,1,1);
               if(!sgn)continue;
               if(check(sgn+1))return true;
            }
        }
        return false;
    }
    int main() {
        int T=read();
        while(T--){
            flag=false;
            n=read();m=read();
            scanf("%s",s+1);
            len = strlen(s+1);
            if(n*m>len||n*m*2<len){
                puts("Impossible");
                continue;
            }
            fo(i,1,len)  s[i]-='0';
            if(gao()){
                fo(i,1,n){
                    putchar('0'+a[i]);
                }
                putchar(' ');
                fo(i,1,m){
                    putchar('0'+b[i]);
                }
                putchar('
    ');
            }else{
                puts("Impossible");
            }
        }
        return 0;
    }
  • 相关阅读:
    C语言单链表创建,插入,删除
    Java乔晓松spring构造函数的注入以及null的注入
    sentilib_语料库项目_search模块的实现
    spring入门(6)set方法注入依赖之null的注入
    Java乔晓松使用Filter过滤器清除网页缓存
    漂亮的弹框
    C#判断各种字符串(如手机号)
    视频数字水印
    数据校验
    SVN 常见问题操作总结
  • 原文地址:https://www.cnblogs.com/hyfer/p/11658049.html
Copyright © 2011-2022 走看看