div. 2
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int a,n,flag=0,ff=0,ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a);
if(a==1)
{
ff=1;
ans++;
if(flag==1)
{
ans++;
flag=0;
}
else if(flag>=2)
{
flag=0;
}
}
else
{
if(ff==0)
{
continue;
}
else
{
flag++;
}
}
}
printf("%d",ans);
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
using namespace std;
int a1[60],a2[60],b[60];
int main()
{
int a,n;
int s1=0x3f3f3f3f,s2=0x3f3f3f3f;
scanf("%d",&n);
a1[0]=0,a2[0]=0;
for(int i=1;i<n;i++)
{
scanf("%d",&a);
a1[i]=a1[i-1]+a;
}
for(int i=1;i<n;i++)
{
scanf("%d",&a);
a2[i]=a2[i-1]+a;
}
a1[n]=a1[n-1];
a2[n]=a2[n-1];
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
}
for(int i=n;i>=1;i--)
{
int ans=a2[n]-a2[i-1];
ans+=b[i];
ans+=a1[i-1];
if(ans<s1)
{
int ss=s1;
s1=ans;
s2=ss;
}
else if(ans>=s1 && ans<s2) s2=ans;
}
printf("%d\n",s1+s2);
return 0;
}
这题需要注意,一个孩子哭了会降低一群孩子的勇气值,期间会有一些孩子的勇气值降为负数,哭泣,退出队伍,又会降低一群孩子的勇气值
一开始我没有考虑到退出队伍,wa了好几把
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std;
#define ll __int64
int k[4005];
struct node
{
int v,d,id;
ll p;
};
node de[4005];
int main()
{
int n,li=0;
queue<node>q1;
scanf("%d",&n);
node s;
for(int i=1;i<=n;i++)
{
scanf("%d%d%I64d",&s.v,&s.d,&s.p);
s.id=i;
q1.push(s);
}
li++;
k[li]=1;
ll ans1=(ll)q1.front().v,ans2=0;
q1.pop();
while(1)
{
int ld=0;
while(!q1.empty())
{
s=q1.front();
q1.pop();
if(ans1)
{
s.p-=ans1;
ans1--;
}
s.p-=ans2;
if(s.p>=0)
{
de[ld]=s;
ld++;
}
else
{
ans2+=(ll)s.d;
}
}
if(!ld) break;
for(int i=1;i<ld;i++) q1.push(de[i]);
ans1=(ll)de[0].v,ans2=0;
li++;
k[li]=de[0].id;
}
printf("%d\n",li);
for(int i=1;i<=li;i++)
{
if(i<li) printf("%d ",k[i]);
else printf("%d\n",k[i]);
}
return 0;
}
将字母看做是静止的
那么每次人的移动规律就是先向右移动一格,再向上,下,前三个方向移动三格
简单队列就可以搞定了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
char s[4][105];
struct node
{
int x,y;
};
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
queue<node>q;
int n,k,flag=0;
node e;
scanf("%d%d",&n,&k);
for(int i=0;i<3;i++)
{
scanf("%s",s[i]);
s[i][n]=s[i][n+1]=s[i][n+2]='.';
if(s[i][0]=='s')
{
e.x=i;
e.y=0;
q.push(e);
}
}
while(!q.empty())
{
e=q.front();
q.pop();
int x=e.x,y=e.y;
if(s[x][y+1]!='.') continue;
for(int i=x-1;i<=x+1;i++)
{
if(i<0 || i>=3) continue;
if(s[i][y+1]=='.' && s[i][y+2]=='.' && s[i][y+3]=='.')
{
if(y+3>=n-1)
{
flag=1;
break;
}
e.x=i,e.y=y+3;
s[e.x][e.y]='#';
q.push(e);
}
}
}
if(flag==1) printf("YES\n");
else printf("NO\n");
}
return 0;
}
【E. Alice, Bob, Oranges and Apples】
模拟gcd的求法
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define ll __int64
ll gcd(ll x,ll y)
{
ll r=1;
while(r)
{
r=x%y;
x=y;
y=r;
}
return x;
}
int main()
{
ll x,y;
scanf("%I64d%I64d",&x,&y);
if(gcd(x,y)==1)
{
while(1)
{
if(x==1) printf("%I64dB",y-1),y=1;
else if(y==1) printf("%I64dA",x-1),x=1;
else if(x<y)
{
printf("%I64dB",y/x);
y%=x;
}
else if(x>y)
{
printf("%I64dA",x/y);
x%=y;
}
if(x==1 && y==1) break;
}
printf("\n");
}
else
{
printf("Impossible\n");
}
return 0;
}
中途相遇法
直接暴力要3^25,肯定超时
所以分成两半求
先处理0~n/2,用map记录(a-b, b-c)对应的a,a、b、c的值见代码
然后处理n/2~n,看是否存在相应的(b-a, c-b)
#include <bits/stdc++.h>
using namespace std;
#define inf 0x7FFFFFFF
int A[30], B[30], C[30];
map<pair<int,int>, int>curr, M;
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
scanf("%d%d%d", &A[i], &B[i], &C[i]);
}
int n1 = n/2;
int last = 1;
for(int i = 0; i < n1; i++) last *= 3;
for(int i = 0; i < last; i++)
{
int k = i;
int a= 0, b=0, c=0;
for(int j = 0; j < n1; j++)
{
int res = k % 3;
k /= 3;
if(res == 0) a += A[j], b += B[j];
if(res == 1) a += A[j], c += C[j];
if(res == 2) b += B[j], c += C[j];
}
if(curr.find({a-b, b-c}) == curr.end() || curr[{a-b, b-c}] < a)
{
curr[{a-b, b-c}] = a;
M[{a-b, b-c}] = i;
}
}
int ans = -0x3f3f3f3f;
int best_a = -1, best_b = -1;
last = 1;
for(int i = n1; i < n; i++) last *= 3;
for(int i = 0; i < last; i++)
{
int k = i;
int a = 0, b = 0, c = 0;
for(int j = n1; j < n; j++)
{
int res = k % 3;
k /= 3;
if(res == 0) a += A[j], b += B[j];
if(res == 1) a += A[j], c += C[j];
if(res == 2) b += B[j], c += C[j];
}
if(curr.find({b-a, c-b}) != curr.end() && curr[{b-a, c-b}] + a > ans)
{
ans = curr[{b-a, c-b}] + a;
best_a = M[{b-a, c-b}];
best_b = i;
}
}
if(best_a < 0) printf("Impossible\n");
else
{
for(int i = 0; i < n1; i++)
{
int res = best_a % 3;
best_a /= 3;
if(res == 0) printf("LM\n");
if(res == 1) printf("LW\n");
if(res == 2) printf("MW\n");
}
for(int i = n1; i < n; i++)
{
int res = best_b % 3;
best_b /= 3;
if(res == 0) printf("LM\n");
if(res == 1) printf("LW\n");
if(res == 2) printf("MW\n");
}
}
return 0;
}
div. 1
【E. Present for Vitalik the Philatelist】
【F. Digits of Number Pi】