• 启航组欢乐赛 题解


    T1 买本子

    这一道题我们可以考虑暴力分解:如果每一个包装所含本子的数量不能总共要买的本子数量整除的话,要买的包装总数要多一,然后求出各包装总共的钱数最后比大小即可。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int main(){
        int n, q, w, e, r, t, y, ans;
        scanf("%d %d%d %d%d %d%d",&n, &q, &r, &w, &t, &e, &y);
        if(n % q) q = (n / q) + 1;
        else q = n / q;
        
        if(n % w) w = (n / w) + 1;
        else w = n / w;
        
        if(n % e) e = (n / e) + 1;
        else e = n / e;
        
        q *= r;
        w *= t;
        e *= y;
        ans = q;
    	if(ans > w) ans = w;
    	if(ans > e) ans = e;
        printf("%d
    ", ans);
        return 0;
    }
    

    T2 哥的八个猜想

    专门开一个函数判断质数,然后按照 (i)(j) 都是质数的条件暴力枚举即可。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    bool p(int num){
    	for(int i = 2; i <= sqrt(num); i++)
    		if(num % i == 0) return false;
    	return true;
    }
    int main(){
    	int n,i,j;
    	cin >> n;
    	for(i = 2; i <= n / 2; i++){
    		j = n - i;
    		if(p(i) && p(j)){
    			cout << n << " = " << i << " + " << j << endl;
    			break;
    		}
    	}return 0;
    }
    
    

    T3 成绩排名

    开一个结构体冒泡排序即可,也可以写一个cmp函数用sort。

    #include<stdio.h>
    struct jxj {
    	int yw;
    	int sx;
    	int yy;
    	int sum;
    	int id;
    };
    int main() {
    	struct jxj a[500],temp;
    	int i,j,n;
    	scanf("%d",&n);
    	for(i=1; i<=n; i++) {
    		scanf("%d%d%d",&a[i].yw,&a[i].sx,&a[i].yy);
    		a[i].sum=a[i].yw+a[i].sx+a[i].yy;
    		a[i].id=i;
    	}
    	for(i=1; i<n; i++)
    		for(j=1; j<=n-i; j++) {
    			if(a[j].sum<a[j+1].sum) {
    				temp=a[j];
    				a[j]=a[j+1];
    				a[j+1]=temp;
    			} else if(a[j].sum==a[j+1].sum&&a[j].yw<a[j+1].yw) {
    				temp=a[j];
    				a[j]=a[j+1];
    				a[j+1]=temp;
    			} else if(a[j].sum==a[j+1].sum&&a[j].yw==a[j+1].yw&&a[j].id>a[j+1].id) {
    				temp=a[j];
    				a[j]=a[j+1];
    				a[j+1]=temp;
    			}
    		}
    	for(i=1; i<=5; i++)
    		printf("%d %d
    ",a[i].id,a[i].sum);
    	return 0;
    }
    

    T4 蛇形矩阵

    纯找规律题,简单的按照行数分类讨论一下即可。

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<cstring>
    using namespace std;
    int main() {
    	int n,i,j,k,t = 0;
    	int a[21][21] = {0};
    	cin >> n;
    	for(k = 1; k <= n; k++){
    		if(k % 2 == 0) {
                for(i = 1; i <= k; i++) {
    				j = n - k + i;
    				t++;
    				a[i][j] = t;
    				a[n + 1 - i][n + 1 - j] = n * n + 1 - t;
    			}
            }else{ 
                for(i = k; i >= 1; i--) {
    				j = n - k + i;
    				t++;
    				a[i][j] = t;
    				a[n + 1 - i][n + 1 - j] = n * n + 1 - t;
    			}
            }
    	}
    	for(i = 1; i <= n; i++) {
    		for(j = 1; j <= n; j++)
    			cout << setw(5) << a[i][j];
    		cout << endl;
    	}
    	return 0;
    }
    

    T5 type

    手写一个字符栈,写入就压栈,删除就弹栈。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,top;
    char a[100001];
    int main() {
    	scanf("%d",&n);
    	while(n--) {
    		char ch[2];
    		scanf("%s",ch);
    		if(ch[0]=='T')cin>>a[++top];
    		else if(ch[0]=='U') {
    			int x;
    			scanf("%d",&x);
    			top-=x;
    		} else {
    			int x;
    			scanf("%d",&x);
    			cout<<a[x]<<endl;
    		}
    	}
    	return 0;
    }
    

    T6 最优布线问题

    最小生成树问题模板,直接跑一遍克鲁斯卡尔即可。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iomanip>
    #include <iostream>
    
    using namespace std;
    
    int main() {
    	int g[201][201];
    	long long int minl[201];
    	bool u[201];
    	int n,i,j,k,tot;
    	memset(g,0xffffff,sizeof(g));
    	cin>>n;
    	for (i = 1; i <= n; i++)
    		for (j = 1; j <= n; j++)
    			cin>>g[i][j];
    	for (i = 2; i <= n; i++)
    		minl[i] = 0x5ffffff;
    	minl[1] = 0;
    	minl[0] = 0x5ffffff;
    	memset(u,true,sizeof(u));
    	for (i = 1; i <= n; i++) {
    		k = 0;
    		for (j = 1; j <= n; j++)
    			if ((u[j]) && (minl[j] < minl[k]))
    				k = j;
    		u[k] = false;
    		for (j = 1; j <= n; j++)
    			if ((u[j]) && (g[k][j] < minl[j]))
    				minl[j] = g[k][j];
    	}
    	tot = 0;
    	for (i = 1; i <= n; i++)
    		tot += minl[i];
    	printf("%d
    ",tot);
    	return 0;
    }
    
    

    T7 迷宫

    直接跑一遍DFS就能得出答案。

    #include<iostream>
    #include<cstring>
    using namespace std;
    int n,s;
    bool b[13][13];
    const int dx[8]={0,0,1,1,1,-1,-1,-1},
              dy[8]={1,-1,1,0,-1,1,0,-1};
    
    void go(int x,int y)
    {
    	if (x==1 && y==n){
    		s++;
    		return;
    	}
    	int i,xx,yy;
    	for (i=0;i<=7;i++)
    	{
    		xx=x+dx[i];
    		yy=y+dy[i];
    		if (b[xx][yy])
    		{
    			b[xx][yy]=false;
    			go(xx,yy);
    			b[xx][yy]=true;
    		}
    	}
    }
    int main()
    {
    	int i,j,x;
    	cin>>n;
    	memset(b,0,sizeof(b));
    	for (i=1;i<=n;i++)
    	    for (j=1;j<=n;j++)
    	    {
    			cin>>x;
    			b[i][j]=(x==0);
    		}
    	s=0;
    	b[1][1]=false;
    	go(1,1);
        cout<<s<<endl;
        return 0;
    }
    
    
    

    T8 S君的甜品店

    Subtask 1:

    直接暴力枚举即可,预计得分 20 分。

    Subtask 2:

    使用 (O(n^3)) 的算法枚举出从 (i)(j) 的每个区间((all_{i,j}))然后用 (dp_i=max(dp_i,dp_{j-1}+all_{j,i})) 的状态转移方程求出最大值。

    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            int f=1;
            for(int k=i;k<=j;k++)
                f=f*a[k]%19260817;
            all[i][j]=f;
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=i;j++)
            dp[i]=max(dp[i],dp[j-1]+all[j][i]);
    

    预计得分50分。

    Subtask 3:

    我们可以发现一个性质,就是 (all_{i,j}=all_{i,j-1} imes a_j) ,即可以由前一个状态转移过来,我们就可以在 (O(n^2)) 的时间复杂度内预处理了。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=19260817;
    ll a[10005],dp[10005],all[10005][10005];
    int main() {
    	int n,f=1;
    	cin>>n;
    	for(int i=1; i<=n; i++) cin>>a[i];
    	for(int i=1; i<=n; i++) {
    		all[i][i]=a[i]%mod;
    		for(int j=i+1; j<=n; j++)
    			all[i][j]=all[i][j-1]*a[j]%mod;
    	}
    	for(int i=1; i<=n; i++) 
    		for(int j=1; j<=i; j++) 
    			dp[i]=max(dp[i],dp[j-1]+all[j][i]);
    	printf("%lld
    ",dp[n]);
    }
    

    值得一提的是,如果你不开 long long 的话,预计和暴力老哥同分哦~

  • 相关阅读:
    基于ubuntu10.04的gccarm安装
    面向连接和非面向连接
    多址技术与复用技术
    NAT——网络地址转换
    IP地址与子网掩码的关系
    ISO的7层模型
    比特率与波特率的比较
    C#中GUID的使用
    iframe刷新父页面
    javascript 获取控件坐标
  • 原文地址:https://www.cnblogs.com/Inversentropir-36/p/13233062.html
Copyright © 2020-2023  润新知