2020-2021年度第二届全国大学生算法设计与编程挑战赛(冬季赛)题解

A题:塔

#include
using namespace std;
/***********************************
观察题目样例给出的高为5层的塔,可以得出以下几个规律
对于一个高为n层的塔而言,首先设最上面一层(顶层)为第一层。
1. 对于第i层而言,其字符的排列规律为:大写字母表中从第1个字符(A)~第i个字符,后又倒序从第i-1个字符~第1个字符(A)。
2. 第1~n-1层每层前都有空格,具体而言,对于第i行,字符前面的空格个数为n-i个。
找出以上规律后,我们就可以根据这些规律构造出答案:层高26的塔。

TIPS:
大写字母'A'为大写字母表第一个字符
对于大写字母表中第i个字符,可以使用'A'+i-1得到。
例如:第5个字符为'E',亦即为:'A'+5-1
***********************************/
int main()
{
	char c1;
	int n=26; //设定塔的层数为26
	for(int i=1;i<=n;i++){ //对塔每一层按照规律进行构造。
		//首先进行输出空格的操作:对于第i行,字符前面的空格个数为n-i个。
		for(int j = 1;j<=26 - i;j++)
			cout<<" ";

		for(int j=1;j<=i;j++){ //按照规律1,输出第1~第i个大写字母。
			c1=j+'A'-1; //第j个大写字母为'A'+j-1
			cout<<c1; //输出第j个大写字母
		}
		for(int j=i - 1;j>=1;j--){ //按照规律1,输出第i-1~第1个大写字母,注意是倒序
			c1=j+'A'-1;
			cout<<c1;
		}
		cout<<endl;//第i行输出结束,进行换行。
	}
	return 0;
}

B题

简单模拟下就行
#include 
using namespace std;

int main(){
  cout << "i love linkezbas je dosadna ovakemijaxaszxdbtddbtddbtddbtddbtddbtd" << endl;
  return 0;
}

E

思路

情况一:如果当前重量是1或者2,背包剩余容量足够,则直接拿进背包。
情况二:背包剩余容量不够,如果当前背包里面有重量为2的草药,那么直接把当前草药丢掉,拿这次的草药就行了(因为一:如果当前草药重量为1,由于不管是重量为1还是重量为2的草药,都只能产生一颗药丸,那么优先选择重量小的放入背包;二:如果当前草药重量为2,那么可以直接不拿【我代码写的是丢掉2再拿2,一个意思】)。
#include 
#include 
using namespace std;

typedef long long ll;

int main(){
    ll v, a = 0, b = 0, ans = 0;
    string s;
    cin >> v >> s;
    ll tot = 0;//背包里的草药重量
    for(int i = 0, n = s.size(); i < n; i++){
        int t = s[i] - '0';
        if(tot + t <= v) {
            if(t == 1) a++, tot++;
            else b++, tot += 2;
        }else{
            if(b > 0) b--, tot -= 2;
            else a--, tot--;
            a++, tot++;
        }
        ans += a + b;
    }
    cout << ans;
    return 0;
}

F

模拟就行了
#include
#include
#include

using namespace std;

typedef pair<string, bool> psb;

const int N = 130010;

char s[N], tmp[N];
vector<psb> str;
bool st[N];
bool blank[N], tmp2[N];
vector<int>ans;
char r[N][130];
int bl[N];

bool check(char ch){
    if(ch >= 'a' && ch <='z') return true;
    if(ch == ' ')return true;
    if(ch >= 'A' && ch <= 'Z') return true;
    return false;
}

int main(){
    int len = 0;
    
    while(~scanf("%c", &s[len++]));
    
    for(int i = 0; s[i]; i++){
        if(s[i] == ' ') blank[i] = true;
        else if(!check(s[i])) tmp2[i] = true;
    }
    
    int z = 1, a = 0, p = 0;
    while(s[a]==' ' || !check(s[a])) printf("%c",s[a++]);
    
    for(int i = a; s[i]; i++){
        if(s[i]==' ') bl[z]++;
        if(!check(s[i])) {
            r[z][p++] = s[i];
            r[z][p] = 0;
            z++, p = 0;
        }
        if(blank[i] || tmp2[i]) continue;
        
        r[z][p++] = s[i];
        
        if(blank[i + 1] || tmp2[i + 1]) {
            r[z][p] = 0;
            z++, p = 0;
        }
    }
    
    for(int i=1;r[i][0];i++){
        if(r[i][0] >= 'A' && r[i][0] <= 'Z') st[i] = true;
        else st[i] = false;
        int c = 1;
        for(; r[i][c]; c++){
            if(r[i][c] >= 'A' && r[i][c] <= 'Z')
                st[i]=false;
        }
        if(c == 1) st[i] = false;
        if(st[i]) tmp[i] = r[i][0];
    }
    
    for(int i = 1; r[i][0]; i++){
       if(bl[i] > 1 || !st[i]){
           
            if(ans.size()>1){
                for(auto j : ans) printf("%c", tmp[j]);
                printf(" (");
                for(int j = 0; j < ans.size()-1; j++)printf("%s ",r[ans[j]]);
                printf("%s", r[ans.back()]);
                printf(")");
                int t = bl[1 + ans.back()];
                while(t--)
                    printf(" ");
            }else if(ans.size() == 1){
                printf("%s",r[ans[0]]);
                int t = bl[1 + ans.back()];
                while(t--)
                    printf(" ");
            }
            while(ans.size()) ans.pop_back();
            if(st[i]) ans.push_back(i);
            else{
               printf("%s", r[i]);
               int t = bl[i+1];
            while(t--)
                printf(" ");
            }
           
        }
        else ans.push_back(i);
    }
    if(ans.size()>1){
        for(auto j:ans)printf("%c",tmp[j]);
            printf(" (");
            for(int j = 0; j < ans.size() - 1; j++)printf("%s ",r[ans[j]]);
            printf("%s",r[ans.back()]);
            printf(")");
            int p = bl[1 + ans.back()];
            while(p--)
                printf(" ");
    }else if(ans.size() - 1 == 0){
                printf("%s",r[ans[0]]);
                int t = bl[1 + ans.back()];
                while(t--)
                    printf(" ");
            }
    return 0;
}

I题

也是模拟下就行
注意n要用double就ok
#include 
using namespace std;

int main(){
    double n;
    int day, x, y;
    
    cin >> n >> x >> y;
    
    double cnt = n;
    bool lock = true, flag = true;
    
    for(day = 1; day <= y; day++)
    {
        cnt = cnt * 2 / 3;
        if(day >= x && lock) cnt = min(n, cnt + n / 2), lock = false;
        if(cnt - n / 32 < 1e-8){
            flag = false;
            break;
        }
    }
    if(flag) printf("YE5!\n%.6lf", cnt);
    else printf("N0!\n%d %.6lf", day, cnt);
    return 0;
}

J题

需要注意鸭子可以放在小数位置上(Debug了好久……需要注意下)
#include
using namespace std;

const double t = 0.00001;

int main() {
	double A, B, a, b;
	cin >> A >> B >> a >> b;
	int n = A / (2 * a - t), m = B / (2 * b - t);
	int lt = A - (2 * a - t) * n, ct = B - (2 * b - t) * m;
	int ans = 0;
	if (lt >= a) n++;
	if (ct >= b) m++;
	ans = n * m;
	cout << ans;
	return 0;
}

K题

主要思路:把所有各位数的和相同的加起来放到一个集合中
#include 
#include 
#include
using namespace std;

const int INF = 0x3f3f3f3f;

vector<int>shu[200010];

int f(int x){
    int res = 0;
    while(x){
        res += x % 10;
        x /= 10;
    }
    return res;
}

int main(){
    
    int ans = INF, n;
    cin >> n;
    
    for(int i = 1; i < 200010; ++i) shu[f(i)].push_back(i);
    
    for(int i = 1, t = 0; i < 200010; ++i){
        if(shu[i].size() >= n){
            t = 0;
            for(int j = 0; j < n; j++) t += shu[i][j];
            ans = min(ans, t);
        }
    }
    
    printf("%d",ans);
    
	return 0;
}

M

最实在的签到题(欣慰)
#include 
#include 
using namespace std;
int main(){
    string s;
    cin >> s;
    if(s == "1") puts("ADPC");
    else puts("12345");
    return 0;
}

你可能感兴趣的:(答案,题解,大学生算法设计与编程挑战赛)