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;
}
1453

被折叠的 条评论
为什么被折叠?



