1. 程式人生 > >codeforces #270題解

codeforces #270題解

題目連結: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;
}