您的位置:首页 > 其它

Codeforces Round #298 (Div. 2) 解题报告 (ABCD)

2015-04-13 11:42 447 查看
A Exam

构造题。构造方法很多。

#include <bits/stdc++.h>

using namespace std;

int main(){
	int n;
	cin>>n;
	if(n<=2){
		cout<<1<<endl;
		cout<<1<<endl;
		
	}else if(n==3){
		cout<<2<<endl;
		cout<<1<<" "<<3<<endl;
	}else if(n==4){
		cout<<4<<endl;
		cout<<3<<" "<<1<<" "<<4<<" "<<2<<endl;
	}else{
		cout<<n<<endl;
		deque<int> que;
		que.push_back(4);
		que.push_back(1);
		que.push_back(3);
		que.push_back(5);
		que.push_back(2);
		for(int i=6;i<=n;i++){
			if(i&1){
				que.push_front(i);
			}else{
				que.push_back(i);
			}
		}
		while(!que.empty()){
			int cur=que.front();
			cout<<cur<<" ";
			que.pop_front();
		}
	}
	return 0;
}


B Covered Path

根据首尾速度和每秒速度差等信息算出最大可能速度。然后分别从头尾往中间增长,贪心取尽可能大的速度,增长到不超过最大速度,注意不能不合要求。

#include <bits/stdc++.h>

using namespace std;

int speed[110];

int main(){
	int v1,v2,t,d;
	cin>>v1>>v2>>t>>d;
	
	int MAX_2=(t-1)*d+v1+v2;	//最大可能速度的两倍
	
	speed[1]=v1;
	speed[t]=v2;
	for(int i=2;i<=t;i++){
		if(speed[i])break;
		speed[i]=speed[i-1]+d;
		bool skip=0;
		while(speed[i]*2>MAX_2){
			speed[i]--;
			skip=1;
		}
		if(skip)break;
	}
	for(int i=t-1;i>=1;i--){
		if(speed[i]){
			while(speed[i]>speed[i+1]+d){
				speed[i]--;
				
			}
			break;
		}
		speed[i]=speed[i+1]+d;
		bool skip=0;
		
		while(speed[i]*2>MAX_2){
			speed[i]--;
			skip=1;
		}
		if(skip)break;
	}
	
	int ans=0;
	for(int i=1;i<=t;i++){
		ans+=speed[i];
	}
	cout<<ans<<endl;
	
	return 0;
}


C Polycarpus' Dice

这题对于每个骰子,只考虑极端情况就可以了。即其他所有骰子全取最大值,计算当前骰子不能大于多少(再大就超了);其他所有骰子全取1,当前骰子不能小于多少(再小就不够了)。注意long long,预先计算所有骰子最大点数和降低复杂度。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

ll d[200010];

int main(){
	ll n,A;
	cin>>n>>A;
	ll sum=0;
	for(int i=1;i<=n;i++){
		scanf("%I64d",&d[i]);
		sum+=d[i];
	}
	
	for(int i=1;i<=n;i++){
		sum-=d[i];
		
		ll test=A-sum;
		ll test2=A-(n-1);
		ll ans=0;
		if(test>1){
			ans+=(test-1);
		}
		if(test2<d[i]){
			ans+=(d[i]-test2);
		}
		sum+=d[i];
		printf("%d ",ans);
	}
	return 0;
}


D Handshakes

首先很容易发现一个规律。每个人进来后,打招呼的人数模3的结果肯定是0,1,2,0,1,2...循环。然后就可以用贪心解决。让每个人进来打招呼人数递增(初始是0),直到递增不上去了,就循环-3找合法的值,找到合法后再往上递增,一直重复这个过程。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

int a[200010];

queue<int> vec[200010];
vector<int> ans;

int main(){
	int n;
	cin>>n;
	
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		vec[a[i]].push(i);
	}
	
	bool ok=1;
	int cur=0;
	
	for(int i=0;i<n;i++){
		if(!vec[cur].empty()){
			ans.push_back(vec[cur].front());
			vec[cur].pop();
			cur++;
		}else{
			while(vec[cur].empty()){
				cur-=3;
				if(cur<0)break;
			}
			if(cur<0)break;
			if(!vec[cur].empty())i--;
		}
	}
	
	if(ans.size()==n){
		printf("Possible\n");
		for(int i=0;i<n;i++){
			printf("%d ",ans[i]);
		}
	}else{
		printf("Impossible");
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: