A. Tokitsukaze and Enhancement
**题意:**Tokitsukaze的HP值有
- HP
,即HP值除以 ,余 ,为 类; - HP
,即HP值除以 ,余 ,为 类; - HP
,即HP值除以 ,余 ,为 类; - HP
,即HP值除以 ,余 ,为 类。
这
玩游戏时,玩家可以增加角色的HP,现在Tokitsukaze希望你最多增加她的HP值为
**输入:**只有一个整数
**输出:**一个整数
**解析:**很简单的一道模拟,按照题目推就可以了。
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
char a,b,c;
char min(char a,char b)
{
if(a<b)
return a;
return b;
}
char solve(int x)
{
if(x%4==1)
return 'A';
else if(x%4==2)
return 'C';
else if(x%4==3)
return 'B';
else
return 'D';
}
int x;
int main()
{
scanf("%d",&x);
a=solve(x);
b=solve(x+1);
c=solve(x+2);
char ans=min(a,min(b,c));
if(ans==a)
printf("0 %c",ans);
else if(ans==b)
printf("1 %c",ans);
else
printf("2 %c",ans);
return 0;
}
B. Tokitsukaze and Mahjong
**题意:**Tokitsukaze在玩日本麻将,在游戏中,她有三张牌,每一张牌都由一个字母和一个数字组成,数字范围从
为了赢这场比赛,她必须达成以下胜利条件之一:
- 手中有三个完全相同的牌,如
,但是 或 则不行。 - 手中有一组序列,由同一字母的三个连续编号的牌组成,如
和 ,但是 或 则不行。
如果她没有达成胜利条件,她就应该画出更多适合自己的牌,她可以画出她想要的任何牌,包括她手中的牌,并且她可以绘制每种牌的数量是无限的。
**输入:**一行,三个字符串,表示Tokitsukaze手中的牌。
**输出:**一个整数,表示她需要绘制最小数量来达成胜利条件的牌的数量。
**解析:**依然很简单的一道模拟,计算牌中不同字母类别的数量,在根据数量分类讨论达成最小数量的牌即可,答案只可能为
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int flag[4],maxx=0,maxi;
struct mahjong
{
int a;
char b;
}s[4];
int cmp(mahjong x,mahjong y)
{
return x.a<y.a;
}
void calc(char p)
{
if(p=='s')
flag[1]++;
else if(p=='m')
flag[2]++;
else
flag[3]++;
}
int main()
{
for(int i=1;i<=3;i++)
{
scanf("%d",&s[i].a);
scanf("%c",&s[i].b);
calc(s[i].b);
getchar();
}
for(int i=1;i<=3;i++)
{
if(flag[i]>maxx)
{
maxx=flag[i];
maxi=i;
}
}
sort(s+1,s+4,cmp);
if(maxx==3)
{
if(s[1].a==s[2].a&&s[1].a==s[3].a)
{
printf("0");
return 0;
}
if(s[1].a+1==s[2].a&&s[2].a+1==s[3].a)
{
printf("0");
return 0;
}
else
{
if(s[1].a==s[2].a||s[1].a==s[3].a||s[2].a==s[3].a)
{
printf("1");
return 0;
}
if(s[1].a+1==s[2].a||s[2].a+1==s[3].a||s[1].a+2==s[2].a||s[2].a+2==s[3].a)
{
printf("1");
return 0;
}
printf("2");
return 0;
}
}
else if(maxx==2)
{
char t;
if(maxi==1)
t='s';
else if(maxi==2)
t='m';
else
t='p';
if(s[1].b==t&&s[2].b==t)
if(s[1].a==s[2].a||s[1].a+1==s[2].a||s[1].a+2==s[2].a)
{
printf("1");
return 0;
}
if(s[1].b==t&&s[3].b==t)
if(s[1].a==s[3].a||s[1].a+1==s[3].a||s[1].a+2==s[3].a)
{
printf("1");
return 0;
}
if(s[2].b==t&&s[3].b==t)
if(s[2].a==s[3].a||s[2].a+1==s[3].a||s[2].a+2==s[3].a)
{
printf("1");
return 0;
}
printf("2");
return 0;
}
else
{
printf("2");
return 0;
}
return 0;
}
C. Tokitsukaze and Discard Items
**题意:**有一个长度为
过程如图所示:

**输入:**两行,第一行三个整数,
**输出:**一个整数,代表操作次数。
**解析:**枚举一编,用
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
long long n,m,k,a[101010];
int main()
{
scanf("%lld%lld%lld",&n,&m,&k);
for(int i=1;i<=m;i++)
scanf("%lld",&a[i]);
long long lazy=0;
long long ans=1;
long long num=1;
for(int i=2;i<=m;i++)
{
if((a[i]-1-lazy)/k!=(a[i-1]-1-lazy)/k)
{
ans++;
lazy+=num;
num=1;
}
else
num++;
}
printf("%lld",ans);
return 0;
}
D. Tokitsukaze, CSL and Stone Game
**题意:**有
失败条件:
- 当前没有石头可取。
- 取走一颗石头后,存在两堆石头个数相同。
- 如果开始的时候有两堆石头相同是没有关系的,只有操作之后还有两堆石头相同才会失败。
**输入:**两行,第一行一个整数
**输出:**如果先手胜,输出”
**解析:**显然取完后最后的石头个数会是从
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,a[101010];
map<int,int> s;
map<int,int>::iterator it;
bool judge()
{
s.clear();
for(int i=1;i<=n;i++)
{
s[a[i]]++;
if(s[a[i]]>2)//如果一开局就有大于两堆石头数目相同,先手必输
return false;
}
int cnt=0;
for(it=s.begin();it!=s.end();it++)
if(it->second==2)//判断石头数目为此数量的堆数是否有两堆
++cnt;//记录有相同数目的两堆石头的出现有多少组
if(cnt==1)//如果整个游戏中只出现了一组有相同数目的两堆石头
for(it=s.begin();it!=s.end();it++)
if(it->second==2)
if(it->first==0||s.find(it->first-1)!=s.end())//设这两堆石头数目为i,如果i=0或者整个游戏中存在数目为i-1的石头堆,即从这两堆中取出1个石头还是会与其他石头数目重复
return false;//先手必输
return cnt<=1;//如果大于1组则先手必输
}
int main()
{
long long sum=0,tot=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];//sum为现在的总石头数
tot+=(i-1);//如果要不重复,则要把石头变成0,1,2,3……n-1这样,tot为这种状态的总石头数
}
if(sum==0||!judge())//如果总石头数为0或者已经判断先手必输
printf("cslnb");
else
{
long long p=sum-tot;//p为从目前状态达到目标状态需要取出的石子数
if(p&1)//如果需要取出奇数颗,先手必胜
printf("sjfnb");
else
printf("cslnb");
}
return 0;
}
E. Tokitsukaze and Duel
**题意:**有一个
**输入:**两行,第一行两个整数
**输出:**如果先手胜,输出”
**解析:**考虑一个先手必胜的情况, 即它可以通过第一步操作就把该串变成全
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
int n,k;
char s[101010];
int sum[101010];//前缀和,可快速通过求一段字符的和判断这段字符是否全为0或1(全为0则和为0,全为1则为这段长度)
bool judge1()//判断能否让先手必胜
{
if(n==k)//如果字符串长度正好为k,先手必胜
return 1;
for(int i=1;i+k-1<=n;i++)//枚举长度为k的字符串的起点
{
int l=i;
int r=i+k-1;//起点和终点位置
int len1=l-1;//起点离开头距离
int len2=n-r;//终点离结尾距离
int L=sum[l-1];//开头到起点的和
int R=sum[n]-sum[r];//终点到结尾的和
if(l==1&&(R==0||R==len2))//特判,如果起点在开头,且终点到结尾的和全为0(R==0)或1(R==len2
return 1;
if(r==n&&(L==0||L==len1))//特判,同上,终点在末尾
return 1;
if((len1==L&&len2==R)||(L==0&&R==0))//普通情况,除这段长度为k的字符外其他字符全为0或1
return 1;
}
return 0;
}
bool judge2()//判断能否平局
{
if(k<(n+1)/2)//如果k小于n的一半,那么如果先手不能必胜,先手可以改变不同字符的另一半位置,让后手不能胜利
return 1;
for(int i=2;i+k-1<n;i++)
{
int l=i;
int r=i+k-1;
int len1=l-1;
int len2=n-r;
int L=sum[l-1];
int R=sum[n]-sum[r];
if((L&&L!=len1)||(R&&R!=len2))//如果有一边不全为0且不全为1
return 1;//平局
}
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
scanf("%s",s+1);
sum[0]=0;
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]-'0'+s[i];
if(judge1())
printf("tokitsukaze");
else if(judge2())
printf("once again");
else
printf("quailty");
return 0;
}
解析中引用了一些这位大佬的思路解析,在此表示感谢。