训练十二

训练十二

题目链接

A.Valya and Letter

题意,给一个信的长宽,和信箱口的长宽,每次可以对折,问最少多少次能把信放进去。

#include<bits/stdc++.h>
using namespace std;

long long n, m, a, b;

int main() {
	scanf("%lld%lld%lld%lld", &n, &m, &a, &b);
	long long x = m, y = n;
	long long ans1 = 0, ans2 = 0;

	while (n > a || m > b) {
		if (n > a) {
			n = (n >> 1) + (n & 1);
			ans1++;
		}
		if (m > b) {
			m = (m >> 1) + (m & 1);
			ans1++;
		}
	}
	while (x > a || y > b) {
		if (x > a) {
			x = (x >> 1) + (x & 1);
			ans2++;
		}
		if (y > b) {
			y = (y >> 1) + (y & 1);
			ans2++;
		}
	}
	printf("%lld\n", min(ans1, ans2));
}

L. How Many Tests

这题开始wa了好几次,忘记了长度是给定的,所以最小也是100…00。唉,这种细节还是总是被坑

题意:一次比赛里面有若干个测试样例文件,按照01,02,03,…,15这样来排序,前面补充0,使其字典序正确。现在给出几个测试样例文件的文件名,问这次比赛最少可能有多少组样例,最多可能有多少组样例。

#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin >> n;
    char s[20];
    int maxn = -1;
    int len;
    for(int i = 0;i < n;i++){
        scanf("%s",s);
        int a;

        sscanf(s,"%d",&a);
        //cout << a << endl;
        maxn = max(maxn,a);
        len = strlen(s);
    }

    //cout << maxn << endl;
    int base = 1;
    for(int i = 0;i < len;i++){
        base *= 10;
    }
    cout << max(base/10,maxn) << endl;
    cout << base - 1 << endl;
}

E. Difficult Problems

队友开始看错题目了,其实就是道水题,都不用二分
就数一数有多少个A,就可以了

题意:每次碰到一道题就写若干个A,不同数量的A代表了不同的难度,每道题的难度都不一样,问最多有几道题。

    #include<bits/stdc++.h>
    using namespace std;

    string s;

    int main(){
        cin >> s;
        int sum = 0;
        for(int i = 0;i < s.size();i++){
            if(s[i] == 'A') sum++;
        }
        //cin >> sum;
        int res = 0;
        int now = 1;
        while(sum - now >= 0){
            sum -= now;
            now++;
            res++;
        }
        cout << res << endl;
    }

G. Flexible Segments

这个题当时应该早点发现的,自己没有拼凑出来,对数字还是没有那么有感觉。不然早该发现的,当时的直觉是是3,4,5那一块地方,但是没有去模拟一下。

结果写了个搜索出来,搜出来是3,汗颜…

题意:给定长度n,问有没有这样连续的n个正整数,将每一个数变成它旁边的数,即x变成x+1或者x-1,之后乘积不变

比如1234 == 2143

显然n为偶数的依次交换顺序即可。

#include<bits/stdc++.h>
//#define int long long
using namespace std;

/*int M;
int flag;
void init(int l,int len){
    M = 1;flag = 0;
    for(int i = 0;i < len;i++){
        M *= (l+i);
    }
}
void dfs(int l,int len,int sum){
    if(flag == 1) return;
    if(M % sum != 0) return;

    if(len == 0){
        flag = 1;
    }
    dfs(l+1,len-1,sum*(l-1));
    dfs(l+1,len-1,sum*(l+1));
}*/

int main(){
    /*int n = 3;
    while(flag != 0){
        int l = 1;
        init(l,n);
        dfs(l,n,1);
        if(flag == 1){
            cout << l;
        }
        l++;
    }*/
    int n;
    while(~scanf("%d",&n)){
        char s[] = "+-";
        if(n & 1){
            if(n == 1){
                cout << "NO" << endl;
            }
            else{
                cout<<"YES" <<endl;
                cout <<"3" <<endl;
                n -= 3;
                cout << "-++";
                for(int i = 0;i < n;i++){
                    cout << s[i&1];
                }cout << endl;
            }
        }
        else{
            cout << "YES" <<endl;
            cout << 1 << endl;
            for(int i = 0;i < n;i++){
                cout << s[i&1];

            }cout << endl;
        }
    }
}

H. Secret Code

当时写炸了,后来换了个思路,就好写很多了。
但还是最后wa了几次,特判的时候没有写好。

题意:给你一些数字(0-9)问用这些数字能组成的最大的密文是多少,一个数字是密文的条件是,每三个连续的数字组成的三位数是三的倍数。

思路:将数分为三种(mod 3),在这三个筒里面把数字从大到小排好,因为只要确定前三个数的种类,后面肯定是依次循环,直接一个一个拿出来就好了。

炸的代码

#include<bits/stdc++.h>
using namespace std;

struct Node{
    int id;
    int sum;
    bool operator < (const Node&x)const{
        return sum > x.sum;
    }
}L[3];

vector<int>R[5];

int main(){

    for(int i = 0;i < 10;i++){
        int t;
        cin >> t;
        for(int i = 0;i < t;i++){
            R[i%3].push_back(i);
        }
    }
    for(int i = 0;i < 3;i++){
        L[i].id = i;
        L[i].sum = L[i].size();
        sort(R[i].begin(),R[i].end());
    }
    sort(L,L+3,greater<int>());

    string r1,r2,r3;

    //case 1: 横着取 0,1,2

    int len1 = L[2].sum;
    if(L[1].sum > L[2].sum) len1++;
    if(L[0].sum > L[2].sum) len1++;
    vector<int>t1;
    for(int i = 0;i < len1;i++){
        t1.push_back(R[0][i]);
        t1.push_back(R[1][i]);
        t1.push_back(R[2][i]);
    }
    if(R[L[1].id].size() > R[L[2].id].size()){
        t1.push_back(R[L[0].id][len1]);
        t1.push_back(R[L[1].id][len1]);
    }
    else{
        if(R[L[0].id].size() > R[L[2].id].size()){
            t1.push_back(R[L[0].id][len1]);
        }
    }
    sort(t1.begin(),t1.end(),greater<int>());
    for(int i = 0;i < t1.size();i++){
        r1 += (char)(t1[i] - '0')
    }

    //case 2:竖着 1, 1, 1
    int len2 = L[0].sum;
    for(int i = 0;i < len2;i++){
        r2 += (char)(R[L[0].id][i] - '0');
    }

    //case 3:竖着 1, 1, 2

    //不 写 了,他妈的,太难写了
    //换个思路写

}

过的代码

#include<bits/stdc++.h>
using namespace std;
vector<int>L[3];

string solve(string tp) {
	if ((tp[0] - '0' + tp[1] - '0' + tp[2] - '0') % 3 != 0) return "";
	//cout << tp << endl;
	int i[] = { 0,0,0 };
	int ind = 0;
	string res = "";
	while (1) {
		int now = (tp[ind] - '0');
		if (i[now] == L[now].size()) break;
		res += (char)(L[now][i[now]] + '0');
		i[now]++;
		ind++;
		ind %= 3;
	}
	return res;
}
int main() {

	for (int i = 0; i < 10; i++) {
		int t;
		cin >> t;
		for (int j = 0; j < t; j++) {
			L[i % 3].push_back(i);
		}
	}
	for (int i = 0; i < 3; i++) {
		sort(L[i].begin(), L[i].end(), greater<int>());
	}
	vector<string>S;
	for (int i = 0; i < 3; i++) {
		for (int j = 0; j < 3; j++) {
			for (int k = 0; k < 3; k++) {
				string tmp = "";
				tmp += (char)(i + '0'); tmp += (char)(j + '0'); tmp += (char)(k + '0');
				//cout << tmp;
				S.push_back(tmp);
			}
		}
	}

	string maxn = "";
	for (int i = 0; i < S.size(); i++) {
		string s = solve(S[i]);
		//cout << S[i] << endl;
		//cout << s << endl;
		if (s.size() > maxn.size()) {
			maxn = s;
		}
		if (s.size() == maxn.size()) {
			if (s > maxn) {
				maxn = s;
			}
		}
	}
	string res = "";
	int flag = 0;
	for (int i = 0; i < maxn.size(); i++) {
		if (flag == 1) {
			res += maxn[i];
		}
		if (!flag && maxn[i] != '0') {
			res += maxn[i]; flag = 1;
		}
		
	}

	if (res == "") {
		cout << "0" << endl;
	}
	else {
		cout << res << endl;
	}
}

D. Berland Railroads

给定n和点的度数序列,求一个树,使其任意两点距离的最大值最小。

队友讨论后决定用贪心做。

#include<bits/stdc++.h>
using namespace std;

int n;
struct Node{
    int id;
    int deg;
    bool operator < (const Node& x)const{
        return deg < x.deg;
    }
}L[200050];

int main(){
    cin >> n;
    for(int i = 0;i < n;i++){
        cin >> L[i].deg;
        L[i].id = i+1;
    }
    sort(L,L+n);
    queue<Node>Q;

    Q.push(L[0]);
    int ind = 1;
    while(!Q.empty()){
        Node tp = Q.front();Q.pop();
        for(int i = 0;i < tp.deg;i++){
            L[ind].deg--;
            Q.push(L[ind]);
            ind++;
            cout << tp.id << " " << L[ind].id << endl;
        }
    }
}

自己没有解决的问题。

I. Torus Travel

C. How to Fail at Programming Contest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值