Educational Codeforces Round 124 (Rated for Div. 2) A-D

A

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

思路
第一轮一定是连续的两个数\(2i-1\),\(2i\)比赛,他们相加是奇数,必然是较小的奇数胜出。现在我们有\(1,3,5...2^{n}-1\)
之后的每一轮比赛一定是两个奇数比赛,他们相加是奇数,必然是大的数胜出。最后的winner是\(2^{n}-1\)
一个超级坑的地方(也可能是我太菜了呜呜呜):
不能直接用\(pow(2,n)\)输出答案!!,因为当结果较大时会自动输出浮点数的形式
否则你会get this而且还会开始怀疑思路出错

code

#define ll long long
using namespace std;
const int N = 100005;
ll n,m,t;

int main(){
	cin>>t;
    while(t--){
        cin>>n;
//        cout<<(pow(2,n)-1)<<endl;
		ll ans=1;
		for(int i=1;i<=n;i++)ans*=2;
		ans-=1;
		cout<<ans<<endl;
    }
	return 0;
} 

B

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

思路
如果要prove him wrong,那么我们要找到满足\(2\vert a_{i}-a_{j}\vert \geq a_{i}+a_{j}\)\(a_{i}\)\(a_{j}\)的关系
不妨设\(a_{i}\geq a_{j}\),于是推出\(a_{i}\geq 3a_{j}\)
注意到题目的要求是\(10^{9}\geq a_{i} \geq 1\),满足上述关系的最长的数列为\(3^{0},3^{1},...3^{18}\),所以n的最大值为19

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 100005;
ll n,m,t;

int main(){
//	cout<<pow(3,18);
	cin>>t;
    while(t--){
        cin>>n;
      	if(n>19){
      		puts("NO");
      		continue;
		}
		puts("YES");
		ll ans=1;
		for(int i=1;i<=n;i++){
			cout<<ans<<" ";
			ans*=3;
		}puts("");
		
    }
	return 0;
} 

C

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

思路
容易发现,必须要满足所有点都位于环内,这样才可满足题目要求。
进一步得出\(a_{1},a_{n},b_{1},b_{n}\)必须和另一排的点相连,而为了最小化cost,每个角上的点应该要连另一排上耗费最小的点,这可以通过for循环一遍得到

code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 200005;
int  n,m,t;
ll a[N],b[N];

int main(){
    cin>>t;
    while(t--){
        cin>>n;
      	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
		for(int i=1;i<=n;i++) scanf("%lld",&b[i]);
		ll ans=abs(a[1]-b[1])+abs(a[n]-b[n]);
		ans=min(ans,abs(a[1]-b[n])+abs(a[n]-b[1]));
		
		ll a1=1e18,an=1e18,b1=1e18,bn=1e18;
		for(int i=1;i<=n;i++){
			a1=min(a1,abs(a[1]-b[i]));
			an=min(an,abs(a[n]-b[i]));
			b1=min(b1,abs(b[1]-a[i]));
			bn=min(bn,abs(b[n]-a[i]));
		}
		ans=min(ans,a1+an+b1+bn);
		
		//a1b1
		ans=min(ans,an+bn+abs(a[1]-b[1]));
		
		//a1bn
		ans=min(ans,an+b1+abs(a[1]-b[n]));
		
		//anb1
		ans=min(ans,a1+bn+abs(a[n]-b[1]));
		
		//anbn
		ans=min(ans,a1+b1+abs(a[n]-b[n]));
		
		cout<<ans<<endl;
    }
	return 0;
} 

D

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

思路
先考虑:怎么样能找到距离最近的点呢?
因为题目的点的范围有点大,最开始想到了二分答案。但是写起来逐渐发现不太对 可能是我水平太差了
其实更直观的想法当然是bfs!如果从已知点出发,走到了未知点,那么未知点的答案就可以根据已知点更新。
具体一点的思路是:先判断和当前点曼哈顿距离=1的点是否都已出现,如果不是就将当前点的dis值设为1,同时记录答案位置;做完上一步之后把他们加进队列,开始bfs更新答案

code

#include<bits/stdc++.h>  ///idea
#define ll long long
using namespace std;
const int N = 200005;
int  n,m,t;
struct node{
	int x;
	int y;
}a[N]; 
int dir[4][2]={0,1,0,-1,1,0,-1,0};
map<pair<int,int>,int>mp;
map<int,pair<int,int>>ans;
int dis[N];

struct node2{
    int id;
    int d;
};
queue<node2>q;

void bfs(){
    while(!q.empty()){
        node2 now=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int x=a[now.id].x+dir[i][0];
            int y=a[now.id].y+dir[i][1];
            int id=mp[make_pair(x,y)];
            if(id){
                if(dis[id]>dis[now.id]+1){
                    dis[id]=dis[now.id]+1;
                    ans[id]=ans[now.id];
                    q.push({id,dis[id]});
                }
            }
        }
    }
}

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&a[i].x,&a[i].y);
        mp[make_pair(a[i].x,a[i].y)]=i;
        dis[i]=1e9;
	}
    //处理所有直接可达的
	for(int i=1;i<=n;i++){
        bool f=0;
        for(int j=0;j<4;j++){
            int x=a[i].x+dir[j][0];
            int y=a[i].y+dir[j][1];
            if(!mp[make_pair(x,y)]){
                f=1;
                ans[i]=make_pair(x,y);
                dis[i]=1;
                break;
            }
        }
    }
    //不能直接抵达的
    for(int i=1;i<=n;i++){
        if(dis[i]==1){
            q.push({i,1});
        }
    }
    bfs();
    //print
    for(int i=1;i<=n;i++){
        printf("%d %d\n",ans[i].first,ans[i].second);
    }
    system("pause");
	return 0;
} 

总结

不知道昨晚怎么回事。。A-C题一共wa6发。。。A也能wa2发我是没想到的😅前3题过了多少人我的排名就是多少。。。。
真就不wa两发不过签到呗
可能还是cf打的少了,打比赛的感觉不对,要继续注意细节+多vp+多写cf C、D题
不过昨晚是第一次用vsc打cf(试图归咎于外因(划掉

posted @ 2022-03-11 12:59  starlightlmy  阅读(185)  评论(0)    收藏  举报