Contest1051 - 2016广工大新生杯决赛

A pigofzhou的巧克力棒

二进制拆分。
2^k对应开心值为2^k - 1。
代码写烦了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>

#define LL long long  

using namespace std;
map<int,int> mp;
void print(){
    mp.clear();
    int num=1,key=0;
    while(num<=1000000000){
        mp[num]=key;
        num*=2;
        key=key*2+1;
    }
}

int main(){
    int T;
    print();
    cin>>T;
    while(T--){
        int n;
        scanf("%d",&n);
        int t=1;
        while(t<=n) t*=2; t=t/2;
        //cout<<mp[2]<<" "<<mp[4]<<endl;
        int ans=0;
        while(n>1){
            if(n>=t){
                n-=t;
                ans+=(mp[t]);
                //cout<<t<<" "<<mp[t]<<endl;
                t/=2;
            }
            else{
                t/=2;
            }
            if(t==0||t==1) break;
        }
        printf("%d\n",ans);
    } 
    return 0;
}

B: Zhazhahe究竟有多二

求N! 中 2的因子个数。

ans=n2+n22+n23+...+n2k

#include <cstdio>
#include <iostream>
#include <cstring>

#define LL long long 

using namespace std;

int main(){
    int T;
    cin>>T;
    while(T--){
        LL n;
        scanf("%lld",&n);
        LL ans=0;
        LL p=2;
        while(p<=n){
            ans += n/p;
            p*=2;
            //cout<<p<<endl;
        }
        printf("%lld\n",ans);
    }
    return 0;
} 

C: 剁手女生节

枚举。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <climits>

#define LL long long 

using namespace std;

int main(){
    int T;
    cin>>T;
    LL n,a,b,c;
    while(T--){
        scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
        int tmp = 4 - (n%4);
        if(tmp==4){
            puts("0");
            continue;
        }
        if(tmp==1){
            LL mn=INT_MAX;
            if(mn>a) mn=a;
            if(mn>(b+c)) mn=b+c;
            if(mn>(c+c+c)) mn=c+c+c;
            printf("%lld\n",mn);
        }
        if(tmp==2){
            LL mn=INT_MAX;
            if(mn>b) mn=b;
            if(mn>(a+a)) mn=a+a;
            if(mn>(c+c)) mn=c+c;
            printf("%lld\n",mn);
        }
        if(tmp==3){
            LL mn=INT_MAX;
            if(mn>c) mn=c;
            if(mn>(a+a+a)) mn=a+a+a;
            if(mn>(a+b)) mn=a+b;
            if(mn>(a+b+b+b)) mn=a+b+b+b;
            printf("%lld\n",mn);
        }
    }

    return 0;
}

D:勤奋的涟漪2

f4(0)=24

然后,13或者12可以呼唤去掉休息日。

#include <cstdio>
#include <iostream>
using namespace std;
int a[200];
int main(){
    int T,n;
    scanf("%d",&T);
    while (T--){
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        int ans=0;
        for (int i=1;i<=n;i++){
            if (a[i]==0) ans++;
            if (a[i]==3&&i>1){
                if (a[i-1]==1) a[i]=2;
                if (a[i-1]==2) a[i]=1;
            }
            if (a[i]==3&&i==1){
                if (a[i+1]==1) a[i]=2;
                if (a[i+1]==2) a[i]=1;
            }
            if (a[i]==a[i-1]&&a[i]!=0&&a[i]!=3){
                a[i]=0;
                ans++;
            }
        }
        printf("%d\n",-24*ans);
    }
}

E:什么排序。。

如果前面的最大值都小于后面的最小值,这就是一个分割点。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <climits>

using namespace std;

int num[1111111];
int   f[1111111];
struct node{
    int x,id;
}a[1111111];

bool cmp(node a,node b){
    if(a.x==b.x){
        return a.id<b.id;
    }
    return a.x<b.x;
}

int main(){
    freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    int T,n;
    cin>>T;
    while(T--){
        memset(f,0,sizeof(f));
        memset(num,0,sizeof(num));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&num[i]);
        for(int i=1;i<=n;i++){
            a[i].x=num[i];
            a[i].id=i;
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;i++)num[a[i].id]=i;
        f[n]=num[n];
        for(int i=n-1;i>=1;i--){
            f[i]=num[i];
            f[i]=min(f[i],f[i+1]);
        }   
        int ans=1,mx=-INT_MAX;
        for(int i=1;i<=n;i++){
            mx=max(mx,num[i]);
            if(f[i+1]>=mx) ans++;
        }
        printf("%d\n",ans);
        if(T!=0)puts("");
    }

    return 0;
}

F:神偷TMK

puts("ab");

G:神偷TMK后续

Ckn

#include <cstdio>
#include <cstring>

#define LL long long 

LL f[100][100];

int main(){
    f[0][0]=1;
    f[1][0]=1;f[1][1]=1;
    for(int i=2;i<=11;i++)
        for(int j=0;j<=i;j++)  f[i][j]=f[i-1][j-1]+f[i-1][j];
    int n,k;
    while(~scanf("%d%d",&n,&k)){
        printf("%lld\n",f[n][k]);
    }

    return 0;
} 

H《为什么会变成这样呢》

这里是链接
Single number 问题,其他数都出现了k(k>1)次,只有一个数出现了一次,求这个数。
考虑把出现了多次数消掉,如果k是偶数,则可用异或法;如果k是奇数,则可以用求和再求余法,出现k次的数模k为0,和里最终剩下的是那个single number %k,还是不行,再利用一个性质,小于k的数对k取模就是这个数本身,分别求single number的每一位

#include <iostream>
#include <cstdio>
using namespace std;
unsigned long long FindFirstBitIs1 (long long num){
    long long indexBit = 0;
    while ((num & 1) == 0 && indexBit < 32){
        num >>= 1;
        ++indexBit;
    }
    return indexBit;
}

long long IsBit1 (long long data, unsigned long long indexof1){
    data >>= indexof1;
    return data & 1;
}

void FindNumsAppearOnce (long long data[], long long n, long long &num1, long long &num2){
    long long result = 0;
    long long i;
    for (i=0; i<n; ++i){
        result ^= data[i];
    }
    unsigned long long indexof1 = FindFirstBitIs1 (result);
    num1 = 0;
    num2 = 0;
    for (i=0; i<n; ++i){
        if (IsBit1 (data[i], indexof1))
            num1 ^= data[i];
        else
            num2 ^= data[i];
    }
}

int main(){ 
    int T;
    cin>>T;
    while(T--){
        long long num1 = 0,num2 = 0;
        long long n;
        scanf("%lld",&n);
        long long *a=new long long[n];
        for(long long i=0;i<n;i++){
            scanf("%lld",&a[i]); 
        }
        FindNumsAppearOnce(a,n,num1,num2);
        printf("%lld %lld\n",min(num1,num2),max(num1,num2));
        delete[] a;
    }
    return 0;
}

I: 只会做水题的jiakin

很烦,但只要理顺就好了。

#include <cstdio>
#include <iostream>
#include <climits>
#include <cstring>

using namespace std;

struct node{
    int x,y;
}g[1111][1111];

bool f[1111][1111];

int main(){
    freopen("input.txt","r",stdin);
    int T,n,m;
    scanf("%d\n",&T);
    for(int cnt=1;cnt<=T;cnt++){
        scanf("%d %d\n",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)scanf("(%d,%d)",&g[i][j].x,&g[i][j].y);
            getchar();
        }
        memset(f,0,sizeof f);
        f[1][1]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(i==1&&j==1) continue;
                if(g[i][j].x==2&&g[i][j].y==4){ //2 4
                    f[i][j]=0;
                    continue;
                }
                if(g[i][j].x==2&&g[i][j].y==5){//2 5
                    f[i][j]=0;
                    continue;
                }

                if(g[i][j].x==2&&g[i][j].y==0&&
                ((g[i][j-1].x==2&&g[i][j-1].y==3)
                ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                ||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(2,0)

                if(g[i][j].x==2&&g[i][j].y==1&&
                ((g[i-1][j].x==2&&g[i-1][j].y==2)
                ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                ||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(2,1)

                if(g[i][j].x==2&&g[i][j].y==2&&
                ((g[i][j-1].x==2&&g[i][j-1].y==3)
                ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                ||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(2,2)

                if(g[i][j].x==2&&g[i][j].y==3&&
                ((g[i-1][j].x==2&&g[i-1][j].y==2)
                ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                ||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(2,3)

                if(g[i][j].x==3&&g[i][j].y==0&&
                ((g[i][j-1].x==2&&g[i][j-1].y==3)
                ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                ||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(3,0)

                if(g[i][j].x==3&&g[i][j].y==3&&
                ((g[i-1][j].x==2&&g[i-1][j].y==2)
                ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                ||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(3,3)

                if(g[i][j].x==3&&g[i][j].y==1){
                    if((g[i-1][j].x==2&&g[i-1][j].y==2)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
                    if(f[i][j]) continue;
                    if((g[i][j-1].x==2&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1]; 
                }
                if(g[i][j].x==3&&g[i][j].y==2){
                    if((g[i-1][j].x==2&&g[i-1][j].y==2)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
                    if(f[i][j]) continue;
                    if((g[i][j-1].x==2&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1]; 
                }
                if(g[i][j].x==4&&g[i][j].y==0){
                    if((g[i-1][j].x==2&&g[i-1][j].y==2)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==2&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==1)
                    ||(g[i-1][j].x==4&&g[i-1][j].y==0)
                    ||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
                    if(f[i][j]) continue;
                    if((g[i][j-1].x==2&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==0)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==2)
                    ||(g[i][j-1].x==3&&g[i][j-1].y==3)
                    ||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1];
                }
            }
        if(f[n][m]){
            printf("Case %d:\n",cnt);
            puts("Well done!");
        }
        else{
            printf("Case %d:\n",cnt);
            puts("What a pity!");
        }
    }

    return 0;
} 

J: 质方数

打表题。

#include <cstdio>
#include <cstring>
#include <climits>
#include <iostream>
#include <cmath>

using namespace std;

int prime[20001];

int isprime(int x){
    for(int i=2;i*i<=x;i++)
        if(x%i==0) return 0;
    return 1;
}

int main(){
    for(int i=2;i<=20001;i++)
        if(isprime(i)) prime[++prime[0]]=i;

    int T;
    scanf("%d",&T);
    while(T--){
        int n,ans;
        scanf("%d",&n);
        int mn=INT_MAX;
        for(int i=1;i<=prime[i];i++)
            if(mn>abs(prime[i]*prime[i]-n)){
                mn = abs(prime[i]*prime[i]-n);
                ans = prime[i]*prime[i];
            }
        printf("%d\n",ans); 
    }

    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值