Codeforces Round #702(div2 A~E ) 补题

本文介绍了Codeforces上的一些编程竞赛题目,包括不同难度级别的解决方案。涉及的题目类型包括等级提升策略、周期性猫的位置预测、比赛平局优化和勾股数问题。文章通过详细解析思路和提供代码示例,帮助读者理解算法应用。
摘要由CSDN通过智能技术生成

链接

https://codeforces.com/contest/1487

A. Arena

(rating : 800)
题意:
每个英雄都有一个等级 , 两个人进行一场战斗时高级的英雄等级+1 , 若同级,则随机+1 .
问最后谁有可能战胜所有英雄 。
思路:
能通过反复揍最拉的那个人来练级… … 所以只要不是唯一最拉的就都可以… …

B. Cat Cycle

(rating:1200)
在这里插入图片描述

题意
有n个位置和两只猫A,B 。
A猫会从n一直移动到1,然后重复 ,n—>1 ,n—>1,n—>1,…
B猫会从1一直移动到n,然后重复,1----->n,1------>n,1----->n , …
当B猫与A猫同时移动到同一个位置时 , B猫会让A猫 , 自己移动到下一个位置上去 。
问k时刻 , B猫在哪?
思路:
(按周期模拟被hack,tle , 相当自闭。。。。。。)
显然 , n%2== 0 时两猫不相遇 。
n%2==1 时,B猫在t时刻会出现在一个固定的位置 , 因为B猫所在位置是周期性变动的。
周期很容易推得出来,但千万不要因为时间“貌似”允许就去模拟。。。。。。
贴波队友的代码,23333
代码:

    #include<bits/stdc++.h> 
    using namespace std;
    int main(){
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		int n,k;
    		scanf("%d%d",&n,&k);
    		if(n%2==0)
    		{
    			printf("%d\n",(k-1)%n+1);
    		}
    		else
    		{
    			int len = n/2;
    			int p = (k-1)/len+k;
    			int ans = (p-1)%n+1;
    			printf("%d\n",ans);
    		}
    		
    	}
    }

C. Minimum Ties

(rating:1500)
题意:
n个人打比赛,两两打一场 ,其中赢+1分,平0分,输-1分 。
你可以决定每场的输赢 。 现在,你需要让每个人得分相等 , 并且平局的次数尽可能少
思路:
想象成一个n个点的无向完全图 。 现在给这个无向完全图加边, 使得每个点(入度-出度)相等 。
由于完全图的性质 , 显然只能让每个点(入-出)= 0 。也就是每个人输的场次 = 赢的场次 。
想到这就容易多了 ,
每个人打 n场比赛:
n为奇数 : 赢n/2场 , 输n/2场 , 平1场。
n为偶数 : 赢n/2场 , 输n/2场。

D. Pythagorean Triples

(rating:1500)
题意:
找到n以内这样的组合 :
a2 + b2 = c2 且 c = a2 - b 。
其中 n<=109 , 次数 t <=104
思路:
移项+平方差公式 , 可以发现就是找一个满足 |c-b| = 1的勾股定理 。 像(3,4,5),(7,24,25)这种 。 进行一下简单的预处理即可 。
代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const ll maxn = 1e5+5;
    ll a[maxn];
    void solve(){
    	for(ll i=1;i<=maxn;i++){
    		if(i%2==0) a[i] = a[i-1];
    		else if(i<3) continue;
    		else{
    			ll aa = i*i;
    			ll b = aa/2;
    			ll c = b+1;
    			if(aa+b*b==c*c)
    			a[i] = a[i-1]+1;
    			else
    			a[i] = a[i-1];
    		}
    	}
    }
    int main(){
    	solve();
    	int t;
    	cin>>t;
    	while(t--){
    		ll n;
    		cin>>n;
    		ll m = sqrt(n+n-1);
    		cout<<a[m]<<endl;
    	}
    }

E. Cheap Dinner(数据结构)

(rating:2000)
在这里插入图片描述

题意:
每餐由一份一道菜 , 一份二道菜 , 一份小吃 , 一份甜点组成 。
现在有很多的一道菜 , 二道菜 , 小吃和甜点 ,各自有不同的价格 。
其中某些一道菜和二道菜 , 某些二道菜和小吃 , 某些小吃和甜点不能一起上 。
问最小价格。
(每种菜的种类<=150000 , 不能出现的关系对 <=200000 ,价格<=1e8)
思路:
算是set的应用模板题吧 。
将关系对存在set中 , 其中s1[i] = j 表示第 i 份二道菜不能与第 j 份一道菜同时出现 。
然后对每道菜从小到大进行排序 。从头开始遍历 , 如果当前 ai 与 bj 不在关系对中 , 则为bj的最优,break 。
用 set.find()函数查找该关系对时 , 复杂度为O(logn) 。

代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 300000;
    set<int> s1[maxn],s2[maxn],s3[maxn];   //s1[i] = j , bi 与 aj 不匹配
    struct node{
    	int id;
    	int val;
    }a[maxn],b[maxn],c[maxn],d[maxn]; 
    int na,nb,nc,nd; 
    int mb,mc,md;
    bool cmp(node A,node B){
    	return A.val<B.val;
    }
    void init(){
    	cin>>na>>nb>>nc>>nd;
    	for(int i=1;i<=na;i++)
    	cin>>a[i].val , a[i].id = i;
    	for(int i=1;i<=nb;i++)
    	cin>>b[i].val , b[i].id = i;
    	for(int i=1;i<=nc;i++)
    	cin>>c[i].val , c[i].id = i;
    	for(int i=1;i<=nd;i++)
    	cin>>d[i].val , d[i].id = i;
    	
    	cin>>mb;
    	int x,y;
    	for(int i=1;i<=mb;i++)
    	cin>>x>>y , s1[y].insert(x);
    	cin>>mc;
    	for(int i=1;i<=mc;i++)
    	cin>>x>>y , s2[y].insert(x);
    	cin>>md;
    	for(int i=1;i<=md;i++)
    	cin>>x>>y , s3[y].insert(x);
    }
     
    void solve(){
    	sort(a+1,a+1+na,cmp);
    	for(int i=1;i<=nb;i++){
    		bool flg = 0;
    		for(int j=1;j<=na;j++){
    			if(s1[i].find(a[j].id)==s1[i].end()){
    				b[i].val = b[i].val + a[j].val;
    				flg = 1;
    				break;
    			}
    		}
    		if(flg==0)
    		b[i].val = 1e9+7;
    	}
    	
    	sort(b+1,b+1+nb,cmp);
    	for(int i=1;i<=nc;i++){
    		bool flg = 0;
    		for(int j=1;j<=nb;j++){
    			if(s2[i].find(b[j].id)==s2[i].end()){
    				c[i].val = c[i].val + b[j].val;
    				flg = 1;
    				break;
    			}
    		}
    		if(flg==0)
    		c[i].val = 1e9+7;
    	}
    	
    	sort(c+1,c+1+nc,cmp);
    	for(int i=1;i<=nd;i++){
    		bool flg = 0;
    		for(int j=1;j<=nc;j++){
    			if(s3[i].find(c[j].id)==s3[i].end()){
    				d[i].val = d[i].val + c[j].val;
    				flg = 1;
    				break;
    			}
    		}
    		if(flg==0)
    		d[i].val = 1e9+7;
    	}
    	
    	int minn = 1e9+7;
    	for(int i=1;i<=nd;i++)
    	minn = min(minn,d[i].val);
    	if(minn==1e9+7)
    	cout<<-1<<endl;
    	else
    	cout<<minn<<endl;
    }
    int main(){
    	init();
    	solve();
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值