Codeforces Round #634 (Div. 3) 題解 (全部7題)


比賽鏈接:https://codeforces.com/contest/1335

A. Candies and Two Sisters

湊一湊大概是 \(\dfrac{n-1}2\)

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
#define int ll
int n;
signed main(){
	int T=read();
	while(T--){
		int n=read();
		cout<<(n-1)/2<<endl;
	}
	return 0;
}

B. Construct the String

比較簡單的方法是 \(b\) 個字符一循環

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
#define int ll
string s;
signed main(){
	int T=read();
	while(T--){
		int n=read(),a=read(),b=read();
		s=""; repeat(i,0,b)s+=char('a'+i);
		while(n){
			int t=min(n,b);
			repeat(i,0,t)putchar(s[i]);
			n-=t;
		}
		puts("");
	}
	return 0;
}

C. Two Teams Composing

統計互不相同的數字個數 \(A\),以及眾數出現次數 \(B\),輸出 \(\max(\min(A-1,B),\min(A,B-1))\),因為要么 \(A\) 送半個給 \(B\) 要么反過來

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
#define int ll
map<int,int> Map;
signed main(){
	int T=read();
	while(T--){
		int n=read(); Map.clear();
		repeat(i,0,n)Map[read()]++;
		int m=0,cnt=0;
		for(auto i:Map){
			cnt++;
			m=max(m,i.second);
		}
		cout<<max(min(cnt-1,m),min(cnt,m-1))<<endl;
	}
	return 0;
}

D. Anti-Sudoku

所有的1變成2,別問我為什么

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
#define int ll
string s;
signed main(){
	int T; cin>>T;
	while(T--){
		repeat(i,0,9){
			cin>>s;
			s[s.find('1')]='2';
			cout<<s<<endl;
		}
	}
	return 0;
}

E2. Three Blocks Palindrome (hard version)

有點考驗代碼功底

首先要弄出一個暴力算法,就是枚舉左指針、右指針、元素種類x、元素種類y,然后統計min(左指針左邊的x個數,右指針右邊的x個數)+倆指針之間y的個數,更新答案

這樣復雜度是 \(O(n^3\cdot200^2)\)(我故意弄得這么暴力)

統計個數可以用前綴和數組實現, \(O(n^2\cdot200^2)\)

然后右指針可以用二分查找實現,因為多了少了都浪費(都在其他情況下統計過了),即先確定左指針,然后在前綴和中查找右指針,其右邊x的個數恰好和左邊一樣, \(O(n(\log n+200)\cdot200)\)

還是過不了,進一步思考,發現左指針如果移動了一格,需要考慮更新的答案只有左指針移動后指向的元素種類(其他元素種類不用考慮,之前考慮過),這樣優化到正確的復雜度 \(O(n(\log n+200))\)

當然如果反過來記錄前綴和與位置的關系可以優化到 \(O(200n)\) 但是我沒有(doge)

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=200010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
//#define int ll
int a[N],s[201][N];
signed main(){
	int T=read();
	while(T--){
		int n=read();
		repeat(i,1,n+1)a[i]=read();
		repeat(c,1,200+1)
			s[c][n+1]=0;
		repeat(c,1,200+1)
		repeat_back(i,1,n+1)
			s[c][i]=s[c][i+1]+(a[i]==c);
		int ans=1;
		repeat(i,1,n+1){
			int c=a[i];
			int pre=s[c][1]-s[c][i+1];
			int p2=upper_bound(s[c]+1,s[c]+n+1,pre,greater<int>())-s[c]-1;
			
			if(p2>i)
			repeat(c2,1,200+1)
				ans=max(ans,s[c2][i+1]-s[c2][p2]+2*pre);
		}
		cout<<ans<<endl;
	}
	return 0;
}

F. Robots on a Grid

有點考驗代碼功底+1

首先所有格子出度為1,很容易發現這是一個基環內向樹(我也是剛學的這個名詞)

因此我們可以把格子映射到整數(好弄一點),構建出一個這樣的圖。每個點必然最終會走進一個環內,因此可以從某些點出發不斷走,直到訪問的點被訪問過,找出所有環,記錄環長

這樣第一問解決了

第二問問的是黑格子里最多放幾個機器人,因此每個環中都要設定一個原點,然后考慮環所在的基環內向樹,計算每個點走到原點需要走幾步,顯然要求(這些步數對環長取模后)兩兩不相等(不然走到原點就撞),因此貪心地多多益善即可

辣雞代碼警告(感覺寫了注釋還是看不懂,就瞎寫了)

#include <bits/stdc++.h>
using namespace std;
#define repeat(i,a,b) for(int i=(a),_=(b);i<_;i++)
#define repeat_back(i,a,b) for(int i=(b)-1,_=(a);i>=_;i--)
int cansel_sync=(ios::sync_with_stdio(0),cin.tie(0),0);
const int N=1000010; typedef long long ll; const int inf=~0u>>2; ll read(){ll x; if(scanf("%lld",&x)==-1)exit(0); return x;}
typedef pair<int,int> pii;
map<int,pii> dir={{'L',{0,-1}},{'R',{0,1}},{'U',{-1,0}},{'D',{1,0}}};
int n,m;
vector<int> a[N]; //這個存的是反圖,上一步
inline int f(int x,int y){return x*m+y;}
int vis[N]; //帶時間戳的vis
bool val[N]; //是否為黑色格子
int to[N],co[N],start[N],len[N],dis[N]; //to是下一步,co是環的id,start是是否為原點,len是某id的環長,dis是走到原點的距離+1
string s;
int dcnt,cocnt,ans1,ans2; //dcnt是vis的時間戳,cocnt是當前環的id
//#define orzz(a) []{cout<<"*****"#a"*****:"<<endl;repeat(i,0,n)repeat(j,0,m)cout<<a[f(i,j)]<<" \n"[j==m-1];}()
void work1(int x0){
	int x=x0;
	dcnt++;
	while(vis[x]==0){
		vis[x]=dcnt;
		x=to[x];
	}
	if(vis[x]==dcnt){
		cocnt++; len[cocnt]=0;
		while(co[x]==0){
			len[cocnt]++;
			ans1++;
			co[x]=cocnt;
			x=to[x];
		}
		start[x]=1;
	}
}
queue<int> q;
bool bkt[N];
void work2(int x0){
	dis[x0]=1;
	q.push(x0);
	int nowco=co[x0];
	int nowlen=len[nowco];
	fill(bkt,bkt+nowlen,0);
	while(!q.empty()){
		int x=q.front(); q.pop();
		if(val[x] && bkt[dis[x]%nowlen]==0){
			ans2++;
			bkt[dis[x]%nowlen]=1;
		}
		for(auto p:a[x]){
			if(dis[p]==0){
				dis[p]=dis[x]+1;
				q.push(p);
			}
		}
	}
}
signed main(){
	int T; cin>>T;
	while(T--){
		cin>>n>>m; cocnt=dcnt=0; ans1=ans2=0;
		fill(vis,vis+n*m,0);
		fill(co,co+n*m,0);
		fill(dis,dis+n*m,0);
		fill(start,start+n*m,0);
		repeat(i,0,n){
			cin>>s;
			repeat(j,0,m)val[f(i,j)]=(s[j]!='1');
		}
		repeat(i,0,n){
			cin>>s;
			repeat(j,0,m)
				to[f(i,j)]=f(i+dir[s[j]].first,j+dir[s[j]].second);
		}
		repeat(i,0,n*m)if(vis[i]==0)work1(i);
		repeat(i,0,n*m)a[i].clear();
		repeat(i,0,n*m)a[to[i]].push_back(i);
		repeat(i,0,n*m)if(start[i])work2(i);
		cout<<ans1<<' '<<ans2<<endl;
	}
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM