CodeTON Round 5 (Div. 1 + Div. 2, Rated, Prizes!) A-C

1842A - Tenzing and Tsondu
题意
两个人,分别有n个和m个宝可梦,设宝可梦a和宝可梦b相互攻击

两方战力在攻击后会变为a-b,b-a,战力小于等于0时宝可梦会消失,问谁会赢

题解
显而易见, 直接比较战力总和即可

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"No"<<endl
#define YES cout<<"Yes"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9+7;
const int N = 5e5+10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T=1;
	cin>>T;
	while(T--)
	{
		int n,m;
		int x=0,y=0;
		cin>>n>>m;
		rep(i,1,n)
		{
			int t;
			cin>>t;
			x+=t;
		}
		rep(i,1,m)
		{
			int t;
			cin>>t;
			y+=t;
		}
		if(x>y)	cout<<"Tsondu"<<endl;
		else if(x==y)	cout<<"Draw"<<endl;
		else if(x<y)	cout<<"Tenzing"<<endl;

		
	}
}

1842B - Tenzing and Books

题意

某人收到了三堆书,每堆n本,每本书有固定的知识值a[i],初始知识值为0,每读一本书都会使原知识值与书本知识值取按位或操作,问是否可以得到期望的知识值。

同时该书必须按一定顺序读,如 4 2 1 3 必须先读4再读2。

题解
很明显,这道题只需要把三次输入放入三个队列中,每次取出队首元素,并将该元素t转成二进制与期望知识值x比较,若转为二进制t=000101,x=000111,则说明t可取,即相同位相等或不相等时t的二进制位为0。

同时,如果知识值已经等于x或三个首元素都不满足条件那么循环结束。

按这种方式进行操作最多只会把三堆书遍历一遍,时间复杂度3*n

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"No"<<endl
#define YES cout<<"Yes"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9+7;
const int N = 5e5+10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T=1;
	cin>>T;
	
	while(T--)
	{
		int n,x;
		cin>>n>>x;
		int ans=0;
	
		queue<int>q[3];
		rep(i,0,2)
		{
			rep(j,1,n)
			{
				int t;
				cin>>t;
				q[i].push(t);
			}
		}
		while(1)
		{
			int p=0;
			if(ans==x)	break;
			rep(i,0,2)
			{
				if(q[i].empty())	continue;
				int t=q[i].front();
				int f=1;
				int a=x,b=t;
				while(1)
				{
					if(a==0&&b==0)	break;
					if( ((a&1)!=(b&1))&&(!(a&1))  )
					{
						f=0;
						break;
					}
					a>>=1;
					b>>=1;
				}
				if(f)
				{
					p=1;
					ans|=t;
					q[i].pop();
				}
			}
			if(!p)	break;
		}

		if(ans==x)	YES;
		else NO;
		
			 
	}
}

1842C - Tenzing and Balls
题意
n个球排成一列, 每个球都有一个特定的颜色值
我们可以选择两个颜色值一样的球, 删除这这两个球之间的所有球(包括这两个球),操作次数不限
问最多能删多少个球

题解
使用两个数组进行动态规划,数组f[i]存前i个数中最多能删多少个,last[x]x上一次出现在什么位置,此时有两种情况,到第i个数时,x=a[i],如果此时x已经遍历过,则判断last[x]是否被计算过,

如果被计算过则k=f[last[x]]+i-last[x]

如果未被计算过则k=f[last[x]]+i-last[x]+1

然后更新f[i]last[i]

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define ll long long
#define NO cout<<"No"<<endl
#define YES cout<<"Yes"<<endl
#define rep(i,a,b)   for(int i=a;i<=b;i++)
const int mod = 1e9+7;
const int N = 5e5+10;
ll inf = (1ll << 60);

//priority_queue <int,vector<int>,less<int> > p;
//priority_queue <int,vector<int>,greater<int> > q;

int a[N];
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int T=1;
	cin>>T;
	
	while(T--)
	{
		int n;cin>>n;
		
		vector<int>f(n+1,0),last(n+1,-1);
		rep(i,1,n)	cin>>a[i];
		int ans=0;
		rep(i,1,n)
		{
			int x=a[i];
			f[i]=max(f[i],f[i-1]);
			if(last[x]!=-1)
			{
				int k=0;
				if(f[last[x]-1]==f[last[x]])	k=f[last[x]]+i-last[x]+1;
				else k=f[last[x]]+i-last[x];
				f[i]=max(f[i],k);
			}
			last[x]=i;
			ans=max(ans,f[i]);
			
		}
		cout<<ans<<endl;
		
		
			 
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值