贪心,有鱼一定钓鱼,没有看后面的无鱼地有多少,可以用前缀和处理出来,比较一下就行了
代码:
#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;
}
不难发现这个字符串的操作不管如何首尾相连后都是一样的,因此我们可以只看首位的位置就可以处理出当时状态的字符串了
代码:
#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;
}
左右手,计算几何题,队友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");
else
printf("left\n");
}
return 0;
}
构造题,只要思路理顺应该不会出错,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;
}
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
签到
剩下的还没补,补了再加