A. Playoff
签到题,第一轮以后剩下的都是奇数,奇数又取最大,答案就是2的n次方-1
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
const int maxn = 0;
const int mod = 1e7+9;
int main(){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
long long ans = pow(2,n)-1;
cout<<ans<<endl;
}
}
B. Prove Him Wrong
公式推导一下,如果YES,那么必然是x1+x2>=2(x2-x1),也就是3x1>=x2,能尽可能让范围在数据内的情况是1 3 9....打个表n<20的时候最后的数在1e9以内
#include<bits/stdc++.h> using namespace std; #define endl '\n' const int maxn = 0; const int mod = 1e7+9; int main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); int t; cin>>t; while(t--){ int n; cin>>n; if(n>=20) cout<<"NO"<<endl; else{ cout<<"YES"<<endl; int a = 1; for(int i = 1;i<=n;i++) { cout << a << " "; a *= 3; } cout<<endl; } } }
C. Fault-tolerant Network
让首尾的度都变成2就可以了,由此推出七种情况(具体看代码吧)
#include<bits/stdc++.h> using namespace std; #define endl '\n' const int maxn = 2e5+10; const int mod = 1e7+9; int a[maxn] = {}; int b[maxn] = {}; int main(){ ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr); int t; cin>>t; while(t--){ int n; cin>>n; for(int i = 1;i<=n;i++) cin>>a[i]; for(int i = 1;i<=n;i++) cin>>b[i]; long long ad1 = 1e9+10,ad2 = 1e9+10; //首尾到其他点的距离 long long bd1 = 1e9+10,bd2 = 1e9+10; //首尾到其他点的距离 long long abh = -1,abw = -1; //首首和尾尾 long long abhw = -1,abwh = -1;//首尾和尾首 abh = abs(a[1]-b[1]); abw = abs(a[n]-b[n]); abhw = abs(a[1]-b[n]); abwh = abs(b[1]-a[n]); for(int i = 1;i<=n;i++){ long long d = abs(a[1]-b[i]); ad1 = min(ad1,d); //首到其他 d = abs(a[n]-b[i]); ad2 = min(ad2,d); } for(int i = 1;i<=n;i++){ long long d = abs(b[1]-a[i]); bd1 = min(bd1,d); d = abs(b[n]-a[i]); bd2 = min(bd2,d); } // cout<<ad1<<" "<<ad2<<" "<<bd1<<" "<<bd2<<" "<<abh<<" "<<abw<<" "<<abhw<<" "<<abwh<<endl; long long ans = min(abhw+abwh,abh+abw); ans = min(ans,abh+ad2+bd2); //首首连 ans = min(ans,abw+ad1+bd1); ans = min(ans,abhw+ad2+bd1); ans = min(ans,abwh+ad1+bd2); ans = min(ans,ad1+ad2+bd1+bd2); cout<<ans<<endl; } }
D. Nearest Excluded Points
多源bfs,目的就是减少单点bfs的反复搜索,由贪心思路可知,两种情况,一种是身边有空的,那么答案就是空的,一种是身边没有空的,那么必然它的答案是身边的某一非空点的答案,再使用队列保证一旦找到就是最近距离之一即可。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f typedef long long ll; using namespace std; const int maxn = 2e5+10; pair<int,int>p[maxn]; map<pair<int,int>,pair<int,int>>ans; set<pair<int,int>>vis; queue<pair<int,int>>q; pair<int,int>now; pair<int,int>nex; int dx[] = {0,0,0,1,-1}; int dy[] = {0,1,-1,0,0}; void bfs(){ while(!q.empty()){ now = q.front(); q.pop(); for(int i = 1;i<=4;i++){ nex = {now.first+dx[i],now.second+dy[i]}; if(vis.count(nex)&&!ans.count(nex)){ //被围死的点的答案和被围着的某个点一样 ans[nex] = ans[now]; q.push(nex); } } } } int main() { int n; cin>>n; for(int i = 1;i<=n;i++) cin >> p[i].first >> p[i].second; for(int i = 1;i<=n;i++) vis.insert(p[i]); /*for(int i = 1;i<=n;i++) cout<<p[i].first<<" "<<p[i].second<<endl;*/ for(int i = 1;i<=n;i++){ for(int j = 1;j<=4;j++) { now = {p[i].first + dx[j], p[i].second + dy[j]}; if(!vis.count(now)) { ans[p[i]] = now; q.push(p[i]); break; } } } bfs(); for(int i = 1;i<=n;i++) cout<<ans[p[i]].first<<" "<<ans[p[i]].second<<endl; }
加油