码迷,mamicode.com
首页 > 其他好文 > 详细

CODEFORCES 704 div2 题解(e待补)

时间:2021-02-25 12:05:04      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:image   个人   ++   字符   cpp   spl   标记   temp   style   

 

 题目

 

 A

技术图片

题意:给四个正整数p,a,b,c  。有三位游泳的人分别在0,a ,2a,3a....;0,b,2b,3b....;0,c,2c,3c.... 的时间来到岸边,另一人将会在P的时间时来到岸边,问p要等多久才能等到至少一个人。

思路:如果p可以整除a,b,c中的某一个则答案为0;否则答案是n -(p%n)的最小值, n为a,b,c。

#include<iostream>
typedef long long ll;
#define rep(a,n) for(a=1;a<=n;++a)
using namespace std;
int main() {
	ios::sync_with_stdio(false);
	ll p, a, b, c, t;
	cin >> t;
	while (t--) {
		cin >> p >> a >> b >> c;
		if (p % a == 0 || p % b == 0 || p % c == 0)cout << 0 << endl;
		else cout << min(min(a - p % a, b - p % b), c - p % c) << endl;
	}
	return 0;
}

  B技术图片

 

题意:只可意会,不可传言(其实是不会,多附一张图

技术图片

 

 思路:总之我们要让大的尽可能在前面,由于每个数只会用一次,我们可以想办法把用过的数标记下来,同时我们还应该知道每个数在数组的下标,然后从后开始遍历;

 

  

#include<iostream>
typedef long long ll;
#define rep(a,n) for(a=1;a<=n;++a)
const  ll maxn = 1e5 + 5;
using namespace std;
int sz[maxn], ans[maxn];
struct p {
	int index;//储存数在sz数组中的下标
	bool us = false;//判断这个数是否被用过
}po[maxn];
int main() {
	ios::sync_with_stdio(false);
	ll t, n, i, j, temp;
	cin >> t;
	while (t--) {
		cin >> n;
		rep(i,n)po[i].us = false;
		temp = n;
		int cnt = 0, cou = 0;
		rep(i,n) {
			cin >> sz[i];
			po[sz[i]].index = i;
		}
		for (i = n; i > 0; i--) {
			if (!po[i].us) {
				for (j = po[i].index; j <= temp; ++j) {
					ans[cou++] = sz[j];
					po[sz[j]].us = true;
				}
				temp = po[i].index - 1;//更新temp
			}
		}
		cout << ans[0];
		for (i = 1; i < cou; ++i)cout << " " << ans[i];
		cout << endl;
	}
	return 0;
}

  C技术图片

 

题意:两个字符串a,b,其中b是a的子串,求最大的宽度,宽度的定义如题

思路:很容易想到贪心。从前往后遍历一遍,得到可能的情况中b中所有字母都映射在a中的最前面,储存在pre;从后遍历一遍,得到映射在最后面的结果,储存在last中;

随后不断更新,over~

 

#include<iostream>
#include<algorithm>
typedef long long ll;
#define rep(a,n) for(a=1;a<=n;++a)
const  ll maxn = 2e5 + 5;
using namespace std;
char a[maxn], b[maxn];
int pre[maxn], last[maxn];
int main() {
   ios::sync_with_stdio(false);
int n, m, i, j = 1, ans=0; cin >> n >> m; rep(i, n)cin >> a[i]; rep(i, m)cin >> b[i]; for (i = 1; j <= m && i <= n; ++i) if (a[i] == b[j]) pre[j++] = i; for (i = n,j=m; j > 0 && i > 0; i--)if (a[i] == b[j])last[j--] = i; rep(i, m-1)ans = max(ans, last[i + 1] - pre[i]); cout << ans << endl; return 0; }

 D技术图片

题意: 构造两个二进制的数,两个数均含有a个0,b个1,它们的差(二进制形式)中含有k个0。PS:所有数中均不可有前导零。

思路:首先特判一下k==0||a==0||b==1的情况,然后考虑一般情况。

对于11xxxxxx0xxx  这样的情况,两者相减等于001111111000  (x为0或者1);这就是构造的方式,除了k>a+b-2的时候我们都可以构造;

      10xxxxxx1xxx                                                                                              代码已经呼之欲出了(虽然但是,写的还是差点心态崩了

 

 

#include<iostream>
#include<algorithm>
typedef long long ll;
const ll mod = 1000000007;
const ll maxn = 2e5 + 5;
const ll inf = 0x3f3f3f3f;
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    ll t, n, i, j, a, temp, k, res, flag, b, c;
    cin >> a >> b >> k;
    if (k == 0) {
        cout << "YES" << endl;
        for (i = 1; i <= b; ++i)cout << 1;
        for (i = 1; i <= a; ++i)cout << 0;
        cout << endl;
        for (i = 1; i <= b; ++i)cout << 1;
        for (i = 1; i <= a; ++i)cout << 0;
        cout << endl;
    }
    else {
        if (a == 0 || b == 1||k>a+b-2)cout << "NO" << endl;
        else {
            cout << "YES" << endl;
            cout << 11;
            int s0 = a - 1, s1 = b - 2;
            for (i = 3; i < 2 + k; ++i) {
                if (s0) {
                    cout << 0;
                    s0--;
                }
                else if (s1) {
                    cout << 1;
                    s1--;
                }
            }
            cout << 0;
            while (1) {
                if (s0 > 0) {
                    cout << 0;
                    s0--;
                }
                else break;
            }
            while (1) {
                if (s1 > 0) {
                    cout << 1;
                    s1--;
                }
                else break;
            }
            cout << endl;
            s0 = a - 1, s1 = b - 2;
            cout << 10;
            for (i = 3; i < 2 + k; ++i) {
                if (s0>0) {
                    cout << 0;
                    s0--;
                }
                else if (s1 > 0) {
                    cout << 1;
                    s1--;
                }
            }
            cout << 1;
            while (1) {
                if (s0 > 0) {
                    cout << 0;
                    s0--;
                }
                else break;
            }
            while (1) {
                if (s1 > 0) {
                    cout << 1;
                    s1--;
                }
                else break;
            }
            cout << endl;
        }
    }
    return 0;
}

 E 待补;

CODEFORCES 704 div2 题解(e待补)

标签:image   个人   ++   字符   cpp   spl   标记   temp   style   

原文地址:https://www.cnblogs.com/ggnpgl/p/14443600.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!