Codeforces Round #693 (contest 1472)

目录

 

A

B

C

D

E


 

A:

https://codeforces.com/contest/1472/problem/A

思路:一张纸横向及纵向所能剪切的数量是固定的,相乘即可。

#include
#include
#define ll long long
using namespace std;

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		ll w,h,n;

		scanf("%lld%lld%lld",&w,&h,&n);
		int ww=0,hh=0;

		while(w % 2 == 0){ww++;w/=2;}
		while(h % 2 == 0){hh++;h/=2;}

		ww = pow(2,ww);
		hh = pow(2,hh);
		ll maxn = ww*hh;

		if(maxn>=n)
			cout<<"YES"<

 

B:

https://codeforces.com/contest/1472/problem/B

思路:若所有糖的重量的总和为奇数,则无论如何,都不可能整分。若总数为偶数,则需判断其除二后结果是奇数还是偶数。

若该结果为偶数,则定可以分。若该结果为奇数,每两个1在一起可以等价于一个2,而奇数的构成是 一堆偶数,加一个1 即可,因此,只要给的数字中有1的出现次数大于等于2即可实现奇数分法的构造。

#include
#include
using namespace std;

int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		int s1=0,s2=0,sum=0;
		for(int i=1;i<=n;i++)
		{
			int t;
			scanf("%d",&t);
			if(t == 1) s1++;
			if(t == 2) s2++;
		}
		sum = s1+2*s2;
		if(sum % 2 == 1)
		{
			cout<<"NO"<=2)
			{
				cout<<"YES"<

 

C:

https://codeforces.com/contest/1472/problem/C

思路:理解题意后 模拟去跑整个过程,记录最大值即可。不过要注意优化! 逆序去进行遍历(类似于记忆化的方式,将从该点至最后跳出所得答案 存储与ta数组对应索引中,前面的点跳到它身上直接读值即可,以次优化时间复杂度)

#include
#include
#define ll long long
using namespace std;

ll a[200005],ta[200005];
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
		ll mmax = -1;

		for(int i=n;i>=1;i--)
		{
			ll tans=0;
			int crs=i;
			
			tans+=a[crs];
			if(crs+a[crs]<=n)
				tans += ta[crs+a[crs]];
			
			ta[crs] = tans;
			mmax = max(mmax,tans);
		}
		cout<

 

D:

https://codeforces.com/contest/1472/problem/D

思路:博弈论,贪心思想,确保每一步都为当前对自己的最优选择。先进行排序,显然要从最大的开始拿。当到你的回合时,你可以选择去选取使自己加分的数,或选取对方的此时最大的数(when 对方选取该数后 会比 当前自己选择自己的数 对自己更不利 即:对方此时最大的数,要大于自己此时最大的数时,去选择对方此时最大的数)。ps.宁可自己不加分,也不能让别人加更多的分。。太贪了orz

#include
#include
#include
#define ll long long
#define N 200005
using namespace std;


ll ev[N],od[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d",&n);
		int evn=0,odn=0;
		for(int i=1;i<=n;i++)
		{
			ll t;
			scanf("%lld",&t);
			if(t % 2 == 0)
			{
				evn++;
				ev[evn]=t;
			}
			else
			{
				odn++;
				od[odn]=t;
			}
			
		}
		sort(ev+1,ev+evn+1);
		sort(od+1,od+odn+1);


		ll aans=0,bans=0;
		int evc=evn,odc=odn;
		for(int i=1;i<=n;i++)
		{
			
			if(i%2 == 1) // alice
			{
				if(evc>=1 && ev[evc]>=od[odc])
				{
					aans+=ev[evc];
					evc--;
				}
				else
				{
					odc--;
				}
			}
			else  // bob
			{
				if(odc>=1 && od[odc]>=ev[evc])
				{
					bans+=od[odc];
					odc--;
				}
				else
				{
					evc--;
				}
			}

		}

		if(aans == bans)
		{
			cout<<"Tie"< bans)
		{
			cout<<"Alice"<

 

 

E:

https://codeforces.com/contest/1472/problem/E

思路:不管坐着躺着,都统一为第一维度(x)是二者中小的数,第二维度(y)是二者中大的数,并以x升序,y降序进行排序处理,非常巧妙,是通过这个方式来保证,tid所标记的点,在当前状态下,其y值是最小的(由于x有序,所以x一定是小于的),这样来判断,如果满足题述要求便记录答案,不满足则更新tid值(以获得更小的b值),从而实现了时间复杂度的降维。

#include
#include
#include
using namespace std;

struct peo{
	long long x,y;
	long long id;
}p[300005];
long long ans[300005];

bool cmp(peo a,peo b)
{
	if(a.x == b.x)
		return a.y>b.y;
	return a.x>T;
	while(T--)
	{
		long long n;
		scanf("%lld",&n);
		long long ta,tb;
		for(long long i=1;i<=n;i++)
		{
			scanf("%lld%lld",&ta,&tb);
			p[i].id=i;
			p[i].x=min(ta,tb);
			p[i].y=max(ta,tb);
		}
		sort(p+1,p+n+1,cmp);
		
		int tid=1;
		for(long long i=1;i<=n;i++)
		{
			long long t=-1;
			if(p[i].y > p[tid].y)
				{t=p[tid].id;}
			if(p[i].y < p[tid].y)
				{tid=i;}
			ans[p[i].id] = t;
			//printf("%s\n", );
			
		}
		for(long long i=1;i<=n;i++)
		{
			printf("%lld",ans[i]);
			if(i!=n) printf(" ");
		}
		cout<

你可能感兴趣的:(Codes,算法,c++,leetcode,排序)