Codeforces Round #827 (Div. 4) A~G

 比赛链接Dashboard - Codeforces Round #827 (Div. 4) - Codeforces

目录

A Sum

B Increasing

C Stripes

D. Coprime 

E Scuza

F Smaller

G Orray


A Sum

题意:给定三个数,问是否存在其中一个数为另外两个数字的和。

思路:直接判断最小的两个数加起来是否等于最大的数即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
int a[3];
void solve() {
	FOR(0, 2)cin >> a[i];
	sort(a, a + 3);
	if (a[0] + a[1] == a[2])yes;
	else no;
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

B Increasing

题意:给定一个长度为 n 的整数数组,判断是否可以重新排列他们,使得数组严格递增。

思路:利用map判断数字是否重复即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
map<int,int>a;
void solve() {
	int n,f=0;
	a.clear();
	cin>>n;
	FOR(1,n) {
		int x;
		cin>>x;
		if(a[x]==1) f=1;
		else a[x]=1;
	}
	if(!f)	yes;
	else no;
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

C Stripes

题意:给定一个 8×8 的网格,其中 . 符号表示空,'R' 符号表示红色,'B' 符号表示蓝色。

每次可能水平地画一道红色,或者垂直地画一道蓝色,后面画的会覆盖前面画的,给出最终结果,问最后画的是什么颜色。

思路:循环判断哪一行或哪一列全是通一个颜色即可,需要注意的是R只能横着涂,B只能竖着涂,像下面的样例:

21684b4d9d3742c9a9c9aa8304b3cd61.png

它的完成方法应该是先涂满B再涂R,所以他的答案应该是R而不是B。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
char s[10][10];
void solve() {
	FOR(1,8)
	FORj(1,8)cin>>s[i][j];
	FOR(1,8) {
		int f=0;
		FORj(1,8) {
			if(s[i][j]!=s[i][1]) {
				f=1;
				break;
			}
		}
		if(!f&&s[i][1]=='R') {
			cout<<s[i][1]<<endl;
			return ;
		}
	}
	FORj(1,8) {
		int f=0;
		FOR(1,8) {
			if(s[i][j]!=s[1][j]) {
				f=1;
				break;
			}
		}
		if(!f&&s[1][j]=='B') {
			cout<<s[1][j]<<endl;
			return ;
		}
	}
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

D. Coprime 

题意:找到下标和最大的两个互质的数。

思路:因为n的范围很大是2~2e5,如果直接枚举会超时,但是可以发现数字大小不超过1000,就算是双重循环也只是1e6并不会超时,所以我们将数字存入map里面,枚举输入中出现过的数字,两两判断数字的gcd是否为1,并且取两两合法的数字的下标最大值即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
void solve() {
	map<int,int>mp;
	int ans=-1;
	int n;
	cin>>n;
	FOR(1,n) {
		int x;
		cin>>x;
		mp[x]=max(mp[x],i);
	}
    for(auto i=mp.begin();i!=mp.end();i++) 
    for(auto j=mp.begin();j!=mp.end();j++) 
    if(__gcd(j->first,i->first)==1)ans=max(ans,i->second+j->second);
   cout<<ans<<endl;
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

E Scuza

给定一个长度为 n <= 2e5 的数组 a[i],表示每级台阶的高度。

给定 q<=2e5 个询问,每个询问给出 k 表示一次最多能跨越的高度,问从 0 开始最多能爬多高。

思路:定义一个sum数组表示台阶高度的前缀和,a[i]数组更新为前i个a[i]的最大值(比如台阶的样子是3 1 4,如果能跨过中间的1那么前面的3也一定能跨过,此时将1更改为3,方便二分查找,因为二分查找是在有序的数组中进行的),最后需要找到最后一个可以跨越过的台阶。我们可以使用upper_bound函数来找到第一个跨越不了的台阶,因为第一个跨越不了的台阶的前一个台阶就是最后能跨越的台阶,最终得到台阶下标k输出前缀sum[k-1]即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
int a[maxn],sum[maxn];

void solve() {
	int n,q;
	cin>>n>>q;
	FOR(1,n) {
		cin>>a[i];
		sum[i]=a[i]+sum[i-1];
	}
	FOR(1,n) {
		if(a[i]<a[i-1])a[i]=a[i-1];
	}
	while(q--) {
		int x;
		cin>>x;
		int k=upper_bound(a+1,a+n+1,x)-a;
		cout<<sum[k-1]<<" ";
	}
	cout<<endl;
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

F Smaller

题意:给定两个字符串 s, t,初始时全为空。

有 q<=2e5 次操作,每次操作选择其中一个串,给定 k <= 2e5,str,往后添加 k 个 str。并询问是否存在一种方式重排 s,t 的字符,使得 s 的字典序严格小于 t 的字典序。

思路:

1. 当字符串t中有不是a的字符时

 (1)只要将这个字符放在字符串t的开头,字符串t就一定比字符串s大(因为s的开头是a)

2.字符串t中全是a时

 (1)若字符串s也全是a,那就比较两个字符串的长度来判断哪个大

 (2)若字符串t全是a而字符串s不全是a,那么字符串s就一定比字符串t大。

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;

void solve() {
	int n,p,k,f=0,f2=0,sum1=0,sum2=0;
	string x;
	cin >> n;
	while (n--) {
		cin >> p >> k >> x;
		if (p == 1) {
			sum1 += k*x.size();
			if (!f2)FOR(0, x.size() - 1) {
				if (x[i] != 'a')f2 = 1;
			}
		} else {
			sum2 += k*x.size();
			if (!f)FOR(0, x.size() - 1) {
				if (x[i] != 'a')f = 1;
			}
		}
		if (f)yes;
		else {
			if (sum1 >= sum2||f2)no;
			else yes;
		}
//		cout<<sum1<<" "<<sum2<<" "<<f<<endl;
	}
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

G Orray

题意:给定长度为 n <=2e5 的数组 a[i],构造 b 数组,其中 b[i] 为 a[1] ... a[i] 或运算的值。要求重排 a[i] 使得 b[i] 的字典序最大。

思路:这题可以说是道暴力题,首先a数组第一个肯定是数组里最大的值,这样b数组的字典序才能最大,再从a数组后面循环遍历,与前面的已经确定顺序的数字进行或运算,找出使确定数组的增长量最多的数字即可。当然只是这样还是会超时:069180ffe05347ab9797be34d10a516f.png

我们需要剪枝,若往后面找的时候没有数字能使或和增长了,就退出循环,因为既然或和不会增长了,后面的数字怎么排或和的最大值都不会改变。

accc3f3bf8b5472eb4a0fddb1202c78e.png

#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include<map>
#include<queue>
#include<set>
#include<math.h>
#define FOR(a,b) for(int i=a;i<=b;i++)
#define ROF(a,b) for(int i=a;i>=b;i--)
#define FORj(a,b) for(int j=a;j<=b;j++)
#define ROFj(a,b) for(int j=a;j>=b;j--)
#define FORk(a,b) for(int k=a;k<=b;k++)
#define ROFk(a,b) for(int k=a;k>=b;k--)
#define mem(i,a) memset(i,a,sizeof(i))
#define ll long long
#define inf 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define int long long
#define yes cout<<"YES"<<endl
#define no cout<<"NO"<<endl
#define pi acos(-1.0)
#define endl '\n'
using namespace std;
const int maxn = 2e5 + 5;
int a[maxn];
void solve() {
	int n, maxi, maxx, t=0;
	cin >> n;
	FOR(1,n)cin >> a[i];
	FOR(1, n) {
		maxx= 0;
		FORj(i,n) {
			if ((t | a[j]) > maxx) {
				maxx = (t | a[j]);
				maxi = j;
			}
		}
		swap(a[maxi], a[i]);
		if (t == maxx) 	break;
		t = maxx;
	}
	FOR(1, n)	cout << a[i] << " \n"[i== n];
}
signed main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	int _;
	cin >> _;
	while (_--)
		solve();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值