A.Clam and Fish
贪心,有鱼一定钓鱼,没有看后面的无鱼地有多少,可以用前缀和处理出来,比较一下就行了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
int n;
char a[maxn];
int s[maxn];
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d",&n);scanf("%s",a+1);int x=0;//鱼饵数int ans=0;for(int i=1;i<=n;i++)s[i]=0;for(int i=1;i<=n;i++)if(a[i]=='0'||a[i]=='1')s[i]=s[i-1]+1;else s[i]=s[i-1];for(int i=1;i<=n;i++){if(a[i]=='0'){if(x){ans++;x--;}}if(a[i]=='2'||a[i]=='3')ans++;if(a[i]=='1'){int y=s[n]-s[i];if(y>x)x++;else {if(x){ans++;x--;}}}}printf("%d\n",ans);} return 0;
}
B.Classical String Problem
不难发现这个字符串的操作不管如何首尾相连后都是一样的,因此我们可以只看首位的位置就可以处理出当时状态的字符串了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sc(a) scanf("%d",&a);
#define pf printf
#define pi acos(-1)
const int mod=1e9+7;
const int N=2e6+10;
int n,l;
char x[N],op;
int main()
{cin>>x;l=strlen(x);scanf("%d\n",&n);int fs=0,a;while(n--){scanf("%c %d\n",&op,&a);if(op=='A'){printf("%c\n",x[(fs+a-1)%l]);}else{fs+=a+l;fs%=l;}}return 0;
}
C.Operation Love
左右手,计算几何题,队友A的,tql,%%%%%
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
double eps=1e-4;
struct cc{double x,y;
}p[25];
int main()
{int t;cin>>t;while(t--){double mmax=0,m[30],k1,k2,b1,b2,c1,c2,c3;int a=-1,f=1;for(int i=0;i<20;i++)scanf("%lf %lf",&p[i].x,&p[i].y);for(int i=0;i<20;i++){m[i]=(p[i].x-p[(i+1)%20].x)*(p[i].x-p[(i+1)%20].x)+(p[i].y-p[(i+1)%20].y)*(p[i].y-p[(i+1)%20].y);if(m[i]>mmax)mmax=m[i],a=i;}if(p[a].x-p[(a+1)%20].x==0)c1=pi/2;else{k1=(p[a].y-p[(a+1)%20].y)/(p[a].x-p[(a+1)%20].x);c1=atan(k1);}if(p[(a+19)%20].x-p[(a+2)%20].x==0)c2=pi/2;else{k2=(p[(a+19)%20].y-p[(a+2)%20].y)/(p[(a+19)%20].x-p[(a+2)%20].x);c2=atan(k2);} c3=atan(2.0/9);//cout<<c1+c3<<' '<<c2<<' '<<c3<<endl;if(fabs(c2+c3-c1)<=eps)f=-f;else if(fabs(c1+c3-c2)<=eps)f=f;else if(fabs(c1+c3-c2-pi)<=eps)f=f;else if(fabs(c2+c3-c1-pi)<=eps)f=-f;if(f==1)printf("right\n");elseprintf("left\n");}return 0;
}
D.Points Construction Problem
构造题,只要思路理顺应该不会出错,NO的状态是在最小和最大之外,最大很好理解就是没有相邻,最小就是最接近正方形的图形,构造就行了
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pi acos(-1)
const int maxn=2e6+10;
const int mod=1e9+7;
double eps=1e-4;
int x[100],y[100],t;
int main()
{int t,f[55],k=0,s=0,p=0;f[1]=4,f[2]=6;for(int i=3;i<=50;i++){if(k){k--;f[i]=f[i-1];}else{if(p==0)s++;p=1-p;k=s;f[i]=f[i-1]+2;}}cin>>t;int n,m,ans;while(t--){cin>>n>>m;if(m>4*n||m<f[n]||m%2==1){printf("No\n");continue;}printf("Yes\n");ans=0;int flag=0;for(int i=1;i<=n;i++){if(m-f[i]-2*(n-i)>=0){ans=0;k=sqrt(i);for(int j=1;j<=k;j++){for(int l=1;l<=k;l++){ans++;x[ans]=j;y[ans]=l;}}p=i-k*k;for(int j=1;j<=min(p,k);j++){ans++;x[ans]=j;y[ans]=k+1;}p-=min(p,k);for(int j=1;j<=p;j++){ans++;x[ans]=k+1;y[ans]=j;}ll o=m-f[i]-2*(n-i);for(int q=1;q<=o/2;q++){ans++;x[ans]=i+10+q;y[ans]=i+10+q;}ll u=n-i-o/2;for(int q=1;q<=u;q++){ans++;x[ans]=1-q;y[ans]=1;}break;}}//cout<<ans<<endl;for(int i=1;i<=ans;i++)printf("%d %d\n",x[i],y[i]);}return 0;
}
E.Two Matchings
dp,不难发现如果是一个序列一定是相邻的两个互指最优,那第二个序列不能和第一个序列有一样的指针,这时不一定是越少越优(WA出的道理QAQ),那我们可以用dp来解决这个问题,首先dp[i]可以由dp[i-4]+四个一组方案和dp[i-6]+六个一组方案推导得到,那我们只要求出最小即可,当然还要先设定初始值dp[4],dp[6],dp[8]
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sc(a) scanf("%d",&a);
#define pf printf
#define pi acos(-1)
const int mod=1e9+7;
const int N=2e6+10;
int n,l,t;
int a[N],dp[N];
char x[N],op;
int main()
{cin>>t;while(t--){cin>>n;for(int i=1;i<=n;i++){scanf("%d",&a[i]);}sort(a+1,a+1+n);ll ans=0;for(int i=1;i<=n;i+=2){ans+=(a[i+1]-a[i]);}dp[4]=a[3]+a[4]-a[1]-a[2];dp[6]=a[6]-a[1]+a[5]-a[4]+a[3]-a[2];dp[8]=dp[4]+a[8]+a[7]-a[6]-a[5];for(int i=10;i<=n;i+=2){dp[i]=min(dp[i-4]+a[i]+a[i-1]-a[i-2]-a[i-3],dp[i-6]+a[i]+a[i-1]+a[i-3]-a[i-4]-a[i-5]-a[i-2]); }ans+=dp[n];cout<<ans<<endl;}return 0;
}
L.Problem L is the Only Lovely Problem
签到
剩下的还没补,补了再加