2017 CCPP 秦皇島
阿新 • • 發佈:2018-11-22
題目:連結
A - Balloon Robot
設機器人從0位置出發, 對於每一個a[i],b[i]算出b[i]時間機器人與s[a[i]]的距離,即所需等待時間,
此時如果將機器人位置向前推進1,則它越過的t[i]時間都會加上m,因為要相遇就要多走一圈,
然後所有的等待時間-1。
程式碼:
#include<bits/stdc++.h> using namespace std; #define ll long long const int maxn=1e5+10; int s[maxn],t[maxn]; int main() { int T;scanf("%d",&T); while(T--) { int n,m,p;scanf("%d%d%d",&n,&m,&p); for(int i=1;i<=n;i++) { scanf("%d",&s[i]); s[i]--; } ll ans=0,cnt=0; for(int i=1;i<=p;i++) { int a,b;scanf("%d%d",&a,&b); b%=m; if(b<=s[a]) t[i]=s[a]-b; else t[i]=m-(b-s[a]); ans+=t[i]; } cnt=ans; sort(t+1,t+p+1); for(int i=1;i<=p;i++) ans=min(ans,cnt-1LL*t[i]*p+1LL*(i-1)*m); printf("%lld\n",ans); } return 0; }
C - Crusaders Quest
模擬即可:
#include<bits/stdc++.h> using namespace std; char t[15]; int num[200],vis[200]; int main() { int T;scanf("%d",&T); while(T--) { scanf("%s",t+1); int len=0,a[4]; int ans=0,k=-1; for(int i=1;i<=9;i++) if(t[i]=='a') a[len++]=i; if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++,k=1; len=0; for(int i=1;i<=9;i++) if(t[i]=='g') a[len++]=i; if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++,k=2; len=0; for(int i=1;i<=9;i++) if(t[i]=='o') a[len++]=i; if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++,k=3; if(ans>=2) printf("3\n"); else if(ans==1) { //cout<<k<<endl; ans=2; if(k==1) { int id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='a') continue; if(t[i]=='g') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='a') continue; if(t[i]=='o') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; } if(k==2) { int id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='g') continue; if(t[i]=='a') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='g') continue; if(t[i]=='o') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; } if(k==3) { int id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='o') continue; if(t[i]=='g') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; id=1,len=0; for(int i=1;i<=9;i++) { if(t[i]=='o') continue; if(t[i]=='a') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans++; } printf("%d\n",min(3,ans)); } else { ans=1; int id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='a') continue; if(t[i]=='g') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='a') continue; if(t[i]=='o') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='g') continue; if(t[i]=='a') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='g') continue; if(t[i]=='o') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='o') continue; if(t[i]=='g') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; id=1;len=0; for(int i=1;i<=9;i++) { if(t[i]=='o') continue; if(t[i]=='a') a[len++]=id; id++; } if(a[0]+1==a[1]&&a[1]+1==a[2]) ans=2; printf("%d\n",ans); } } return 0; }
E - String of CCPC
每加一個字元最多增加一個CCPC,因此至多新增一個字元,特判幾種情況即可。
程式碼:
#include<bits/stdc++.h> using namespace std; const int maxn=2e5+10; char t[maxn]; int main() { int T;scanf("%d",&T); while(T--) { int bb=0; int n;scanf("%d",&n); scanf("%s",t+1); t[0]=t[n+1]=t[n+2]=t[n+3]=t[n+4]=t[n+5]=t[n+6]='#'; int ans=0; for(int i=4;i<=n;i++) if(t[i-3]=='C'&&t[i-2]=='C'&&t[i-1]=='P'&&t[i]=='C') ans++; for(int i=3;i<=n;i++) { if(t[i]=='C'&&t[i-1]=='P'&&t[i-2]=='C'&&t[i-3]!='C') bb=1; if(t[i]=='P'&&t[i-1]=='C'&&t[i-2]=='C'&&t[i+1]!='C') bb=1; if(t[i]=='C'&&t[i-1]=='C'&&t[i-2]=='C'&&(t[i+1]!='P'||t[i+2]!='C')) bb=1; } printf("%d\n",ans+bb); } return 0; }
只有兩種選擇,把m右邊的改為R,或把m左邊的改為L.
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
char t[maxn];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n,m;scanf("%d%d",&n,&m);
scanf("%s",t+1);
int ans1=0,ans2=0;
for(int i=2;i<m;i++)
if(t[i]=='R') ans1++;
for(int i=m+1;i<n;i++)
if(t[i]=='L') ans2++;
if(t[m]=='L') ans2++;
else ans1++;
printf("%d\n",min(ans1,ans2));
}
return 0;
}
M - Safest Buildings
小圓必須包含在大圓內,因此小圓的圓心有一個範圍,小圓的圓心構成的集合也是一個圓。記為O,
對於每個點,以此點為圓心,以r為半徑構成的圓與圓O重合的面積除以圓O的面積就是概率。
此處無需求相交面積,只要sqrt(a*a+b*b)<=abs(R-2*r) 概率一定是最大,否則只需比較a*a+b*b即可。
程式碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int x[maxn],y[maxn];
int ans[maxn];
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n,R,r;scanf("%d%d%d",&n,&R,&r);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
for(int i=1;i<=n;i++)
{
if(R>=2*r&&x[i]*x[i]+y[i]*y[i]<=(R-2*r)*(R-2*r))
ans[i]=0;
else if(R<2*r&&x[i]*x[i]+y[i]*y[i]<=(2*r-R)*(2*r-R))
ans[i]=0;
else
ans[i]=x[i]*x[i]+y[i]*y[i];
}
//for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
//cout<<endl;
int mi=1e9,cnt=0;
for(int i=1;i<=n;i++)
{
if(ans[i]<mi) mi=ans[i],cnt=1;
else if(mi==ans[i]) cnt++;
}
printf("%d\n",cnt);
bool bb=0;
for(int i=1;i<=n;i++)
{
if(ans[i]!=mi) continue;
if(bb) printf(" ");
printf("%d",i);
bb=1;
}
printf("\n");
}
return 0;
}