codeforces #270題解
阿新 • • 發佈:2019-01-04
題目連結:http://codeforces.com/contest/472
A:要求輸入一個n,拆分成兩個素數的和即可
// >File Name: codeforces270A.cpp // > Author: Webwei #include<iostream> #include<algorithm> #include<cmath> using namespace std; int judge(int x) { int n=sqrt(x); for(int i=2;i<=n;i++) { if(x%i==0) return 0; } return 1; } int main() { int n; cin>>n; for(int i=4; ;i++) { int t=n-i; if(!judge(t)&&!judge(i)) { cout<<i<<" "<<t<<endl; return 0; } } }
B:contains two integers n and k (1 ≤ n, k ≤ 2000) — the number of people and the maximal capacity of the elevator.
第一行給出人數和電梯的最大容納數量
The next line contains n integers: f1, f2, ..., fn (2 ≤ fi ≤ 2000), where fi denotes the target floor of the i-th person.
接下來就是地一個人要到第fi層樓,電梯每上一層一秒,問所有人到達自己想要到達的樓層最少需要幾秒.最後電梯要返回第一層.
思路:就是電梯肯定要到達最高層,返回第一層,這樣可以在電梯允許人數的範圍內先送最高層,次高層稍帶就上去了.接著依次模擬此過程
// >File Name: codeforces270B.cpp// > Author: Webwei#include<iostream>#include<algorithm>usingnamespace std;int cmp(int a,int b){return a>b;}int main(){int n,k;
cin>>n>>k;int a[2010];for(int i=1;i<=n ;i++) cin>>a[i],a[i]-=1;
sort(a+1,a+1+n,cmp);
cout<<endl;int sum=0;if(k>=n) cout<<2*a[1]<<endl;else{for(int i=1;i<=n;i=i+k)
sum+=a[i]*2;
cout<<sum<<endl;}return0;}
C:不確定因素.每一個人可以在兩個名字中選擇一個.問最後一次排下來是否可以按照字典序輸出.貪心就好了.
// >File Name: codeforces270C.cpp// > Author: Webwei#include<iostream>#include<algorithm>usingnamespace std;struct node{
string a;
string b;};
node v[100010];int a[100010];int main(){
ios::sync_with_stdio(0);
cin.tie(0);int n;
cin>>n;for(int i=0;i<n;i++){
cin>>v[i].a>>v[i].b;if(v[i].a>v[i].b){
string s=v[i].a;
v[i].a=v[i].b;
v[i].b=s;}}for(int i=0;i<n;i++){
cin>>a[i];
a[i]-=1;}int flag=1;for(int i=1;i<n;i++){if(v[a[i]].a>v[a[i-1]].a||(v[a[i]].a>v[a[i-1]].b))
v[a[i]].b=v[a[i]].a;elseif(v[a[i]].b>v[a[i-1]].a||v[a[i]].b>v[a[i-1]].b)
v[a[i]].a=v[a[i]].b;else{
flag=0;break;}}if(flag==1) cout<<"YES"<<"\n";else cout<<"NO"<<"\n";return0;}
D:這個題就是給出一個臨接矩陣,已知兩點之間的最小距離,問是否可以構成一棵樹.
這個官方給的題解是最小生成數然後dfs搜尋任意兩點之間的距離看是否滿足.這裡有一個大神的思路和程式碼,受教了.
將1作為根,對於任意兩點存在兩種關係:
1.一個點位於另一個點的子樹上。兩點到1的距離之差絕對值等於兩點距離。
2.兩個點在某一個點的不同子樹上。兩點到1距離之和減去兩點距離等於兩倍某個點到1的距離。
這樣不需要管父節點是哪一個,只要保證存在就行了。
判斷這兩種情況就可以了。
當然在開始的時候要注意一些特殊情況的判斷,預處理一下。#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
int n;
long long mp[2005][2005];
map <long long,int> m;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%I64d",&mp[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if((i==j && mp[i][j]) || (i!=j && mp[i][j]==0) || mp[i][j]!=mp[j][i])
{
cout<<"NO"<<endl;
return 0;
}
}
for(int i=1;i<=n;i++)
m[2*mp[1][i]]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if((mp[i][j]==abs(mp[1][i]-mp[1][j])) || m[mp[1][j]+mp[1][i]-mp[i][j]])continue;
cout<<"NO"<<endl;
return 0;
}
}
cout<<"YES"<<endl;
return 0;
}