7.29日训练赛总结 题解

A

模拟 需要考虑的是 gcd互相加的过程中最大公约数并不便 所以加上y之后直接算就行 不用再模拟m-n步

#include
#define For(i, s, e) for(int i = s; i < e; i++)
#define For_(i, s, e) for(int i = s; i > e; i++)
#define sd1(i) scanf("%d", &i)
#define sd2(i, j) scanf("%d%d", &i, &j)
#define sl2(i, j) scanf("%lld%lld", &i, &j)
#define sd3(i, j, k) scanf("%d%d%d", &i, &j, &k)
#define LL long long 
#define ULL unsigned long long
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
using namespace std;
#define LL long long
LL f[100005];
int gcd(LL a,LL b){
    if(b == 0) return a;
    else return gcd(b,a % b);
}

int main(int argc,char* argv[]) {
    int T,n,m,x,y,kase = 0;
    sd1(T);
    while(T--) {
        scanf("%d %d %d %d",&x,&n,&y,&m);
        f[0] = 0; f[1] = x; 
        For(i, 2, n+2) f[i] = f[i -1] + f[i - 2];
        f[n+1] += y;
        //For(i,n+2,m+2) f[i] = f[i - 1] + f[i - 2];
        //for(int i=0; i <= m+1; i++) printf("%lld ",f[i]);
        //printf("\n");
        printf("Case %d: %lld\n",++kase,gcd(f[n],f[n+1]));
    }


    return 0;
}

B

水题
上代码:

#include 
using namespace std;

bool cmp(int a, int b) {
    return a > b;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int T; cin >> T;
    for (int t = 1; t <= T; t++) {
        int d[2] = { 0 }; cin >> d[0] >> d[1];
        sort(d, d + 2, cmp);
        if (d[0] == 1 && d[1] == 1) {
            printf("Case %d: Habb Yakk\n", t);
        }
        else if (d[0] == 2 && d[1] == 2) {
            printf("Case %d: Dobara\n", t);
        }
        else if (d[0] == 3 && d[1] == 3) {
            printf("Case %d: Dousa\n", t);
        }
        else if (d[0] == 4 && d[1] == 4) {
            printf("Case %d: Dorgy\n", t);
        }
        else if (d[0] == 5 && d[1] == 5) {
            printf("Case %d: Dabash\n", t);
        }
        else if (d[0] == 6 && d[1] == 6) {
            printf("Case %d: Dosh\n", t);
        }
        else if ((d[0] == 5 && d[1] == 6) || (d[0] == 6 && d[1] == 5)) {
            printf("Case %d: Sheesh Beesh\n", t);
        }
        else {
            printf("Case %d: ", t);
            for (int j = 0; j < 2; j++) {
                if (d[j] == 1) {
                    printf("Yakk");
                }
                else if (d[j] == 2) {
                    printf("Doh");
                }
                else if (d[j] == 3) {
                    printf("Seh");
                }
                else if (d[j] == 4) {
                    printf("Ghar");
                }
                else if (d[j] == 5) {
                    printf("Bang");
                }
                else if (d[j] == 6) {
                    printf("Sheesh");
                }
                if (j == 0) {
                    printf(" ");
                }
                else {
                    printf("\n");
                }
            }
        }
    }
    return 0;
}

C

多重背包 先上代码 等学了再来解释


#include
#include
#include
#include
#include
using namespace std;
#define N 10000
__int64 s,dp[N],ans,v[N],c[N];
int main()
{
	int i,j,k,n,t,a,kase=0;;
	cin>>t;
	while(t--)
	{
		cin>>s>>n;
		__int64 Max=0;
		for(i=1;i<=n;i++)
		{
		  cin>>v[i]>>c[i];
		 Max=max(Max,c[i]);
	    }
	    ans=0;
	    for(i=1;i<=Max&&i<=s;i++)
	    	if(s%i==0)
	    	{
	    		__int64 kk=s/i;
	    		memset(dp,0,sizeof(dp));
	    		dp[0]=1;
	    		for(j=1;j<=n;j++)
	    		 {
	    		 	if(c[j]>=i)
	    		 	{
	    		 		for(k=kk-v[j];k>=0;k--)
	    		 		dp[k+v[j]]+=dp[k];
					 }
				 }
				ans+=dp[kk]; 
			}
		 cout<<"Case "<<++kase<<": "<<ans<<endl; 
	}
	return 0;
}

G

题意:
二叉树 给高度和叶子节点数 求最大可能节点数
思路:
由二叉树性质 由2到L 逐渐*2 并乘以高度相加

#include
#define For(i, s, e) for(int i = s; i < e; i++)
#define For_(i, s, e) for(int i = s; i > e; i++)
#define sd1(i) scanf("%d", &i)
#define sl1(i) scanf("%lld", &i)
#define sd2(i, j) scanf("%d%d", &i, &j)
#define sl2(i, j) scanf("%lld%lld", &i, &j)
#define sd3(i, j, k) scanf("%d%d%d", &i, &j, &k)
#define ULL unsigned long long
#define INF 0x3f3f3f3f
const double PI = acos(-1.0);
using namespace std;
#define LL long long

LL T;
int main(){
	sl1(T);
	LL L, H, h = 0, sum = 1;
	LL cas = 1;
	while(T--){
		sum = 1;
		h = 0;
		sl2(H, L);
		if(L == 1){
			printf("Case %lld: %lld\n",cas++,H+1);
			continue;
		}	
		//LL sum;
		LL i = 0;
		for(i = 2; i <= L; i *= 2){
			if(i != 2){
				LL s = (H-h) * (i/2);
				sum += s;
				//cout << sum << endl;
			}
			else{
				LL s = (H-h) * 2;
				sum += s;
				//cout << sum << endl;
			}	
			h++;	
		}
		
		if(L != i / 2){
			LL left = L - i / 2;
			sum += left*(H-h);
			//cout << sum << endl;
		}
		printf("Case %lld: %lld\n",cas++,sum);
		
	}
	return 0;
}

I

干了半天 限时5000ms 最快5003ms
错误代码:

#include 
#include 
#include 
#include  
#include 
#define  Maxn 100005
using namespace std;
string s[Maxn],ss;                                                                                        
int n,typed[Maxn],tot;
int len;
int judge() {
    int len = ss.length();
    for(int i = 1; i <= tot; i++) {
        if(s[i].length() == len){
	        int flag = abs((ss[0] - s[i][0]));
	        for(int j = 1; j < len; j++) {
	            if (abs((ss[j] - s[i][j])) != flag) break;
	            if(j == len - 1) return 0; 
	        }
	    }    
    }
    return 1;
}

int main() {
    int T,kase = 0; scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        int Ans = 1; tot = 1;
        cin >> s[1];
        for(int i = 2; i<=n; i++) {
        	char c[10];
        	scanf("%s", c);
        	ss = c;
            if(judge()) {
                Ans++; 
				tot+=1;
                s[tot] = ss;
            }
        }
        printf("Case %d: %d\n",++kase,Ans);

    }
}

题解:
用的dfs

?include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 9;
bool exist[5][maxn] = {};
char s[6] = {};
int len;
void dfs(int num ,int p ,int d){
	if(p == len){
		if(s[p] + d <= 9) exist[len][num * 10 + s[p] + d] = 1;
		if(s[p] - d >= 0) exist[len][num * 10 + s[p] - d] = 1;
		return;
	}
	if(s[p] + d <= 9) dfs(num * 10 + s[p] + d ,p + 1 ,d);
	if(s[p] - d >= 0) dfs(num * 10 + s[p] - d ,p + 1 ,d);
}
int solve(){
	int n ,cnt = 0;
	scanf("%d" ,&n);
	memset(exist ,0 ,sizeof exist);
	while(n--){
		scanf("%s" ,s);
		len = strlen(s) - 1;
		int x = atoi(s);
		if(exist[len][x]) continue;
		cnt++;
		for(int i = 0; i <= len; i++)
			s[i] -= '0';
		exist[len][x] = 1;
		for(int i = 1; i <= 9; i++)
			dfs(0 ,0 ,i);
	}
	return cnt;
}
int main(){
	int kase;
	scanf("%d" ,&kase);
	for(int i = 1; i <= kase; i++)
		printf("Case %d: %d\n" ,i ,solve());
}

你可能感兴趣的:(比赛题解)