1 条题解
-
0
我们把颗球看做是
一轮
。对于每一轮来说,如果在这一轮开始前,比分是
a:b
,那么这一轮结束后,比分是多少就是确定的。很明显可以看出来的一点是,开始时候两个人的当前局得分如果都的话,同时把两个人的分数减去同样的分数,使得两个人的分数都,是不会影响这一轮结果的。
那么,我们开三个数组,分别记录:
:最早什么时候,遇到这一轮开始前,比分是。
:这个时候,小明/小红一共赢了多少局。
那么,当我下一次在时候(此时总比分是)模拟遇到同样的时,就可以视作,模拟的过程是每一个周期,每个周期内,大局的得分都是。
直接跳过这个超级大周期,然后模拟完剩余的时间即可。
由于开始的比分最多只有种,因此模拟的总次数不会超过。
#include <bits/stdc++.h> #define maxn 1000005 #define ll long long #define mod 998244353 using namespace std; ll t[17][17]; ll sa[17][17],sb[17][17]; ll n,k; string s; ll a=0,b=0,A=0,B=0; ll tim=0; void moni() { for (int i=0;i<k;i++) { tim++; if (s[i]=='A') a++; else b++; if (max(a,b)>=11 && abs(a-b)>=2) { if (a>b) A++; else B++; a=b=0; } if (tim==n) {cout<<A<<":"<<B<<endl; exit(0);} } } int main() { cin>>n>>k; cin>>s; memset(t,-1,sizeof(t)); t[0][0]=0; while (true) { moni(); if (a==b && a>11) a=b=11; if (min(a,b)>=11 && a!=b) {if (a>b) a=12,b=11; else a=11,b=12;} if (t[a][b]!=-1) //曾经出现过 { ll da=A-sa[a][b],db=B-sb[a][b]; //deltaA,deltaB ll zhouqi=tim-t[a][b]; //周期大小 ll quan=(n-tim)/zhouqi; A+=da*quan; B+=db*quan; tim+=quan*zhouqi; if (tim==n) {cout<<A<<":"<<B<<endl; return 0;} while (true) moni(); } else { t[a][b]=tim; sa[a][b]=A; sb[a][b]=B; } } return 0; }
- 1
信息
- ID
- 1426
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 211
- 已通过
- 15
- 上传者