[计蒜客] n 子棋
n 子棋
Description
小 A 和小 B 在玩 nn 子棋, nn 子棋游戏的规则是,两人在一个左上角是 (1,1)(1,1),右下角是 (n,n)(n,n) 的 n \times nn×n 棋盘中交替落子,只要有一方的 nn 个棋子在同一行或者同一列或者同一条对角线上,对方就输了。
游戏由小 A 先手,一共进行了 mm 回合,请你来当裁判,帮他们裁定胜负。
游戏结束的条件是:
- 出现胜负;
- 所有回合结束。
一旦满足上述任意一个条件,游戏立即结束,后续回合无效。
Input
第一行两个整数 n,mn,m ,表示棋盘大小和回合数 。
接下来 mm 行,每行两个数 x,yx,y,表示当前轮到的人会在第 xx 行第 yy 列放一个棋子。
output
输出一行,包含一个整数 xx ,表示游戏结束的回合,和一个字符串 SS 表示游戏结果,用一个空格隔开。
若小 A 赢了 SS 为"milk!"
;小 B 赢了 SS 为"juice!"
;否则 SS 为"drawn!"
。
对于前 10\%10% 的数据,保证 n=1n=1;
对于前 30\%30% 的数据,保证 1\leq n \leq 21≤n≤2;
对于前 70\%70% 的数据,保证 1\leq n \leq 501≤n≤50;
对于前 90\%90% 的数据,保证 1\leq n\leq 5001≤n≤500;
对于 100\%100% 的数据,保证 1\leq n\leq 10^5, 0\leq m \leq \min(3\times 10^5, n^2)1≤n≤105,0≤m≤min(3×105,n2)。
保证最初棋盘是空的且游戏结束前所有操作均合法。
Examples
Input
2 4 1 1 2 2 2 1 1 2
Output
3 milk!
正确解法:
对每行、每列,两条对角线各用一个变量维护(初值为0) ,
轮到小 A 就++对应变量、轮到小 B 则--,同时检查对应变量绝对值是否为 n。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<string> 6 using namespace std; 7 const int N=100000+100; 8 int n,m,x,y; 9 int a[N]={0},b[N]={0},cnt1=0,cnt2=0; 10 int f=1; 11 int main() 12 { 13 cin>>n>>m; 14 for(int i=1;i<=m;i++,f=-f) 15 { 16 cin>>x>>y; 17 a[x]+=f; 18 b[y]+=f; 19 if(x==y) 20 cnt1+=f; 21 if(x==n-y+1) 22 cnt2+=f; 23 if(abs(a[x])==n||abs(b[y])==n||abs(cnt1)==n||abs(cnt2)==n) 24 { cout<<i<<" "; 25 if(f==1) cout<<"milk!"<<endl; 26 else cout<<"juice!"<<endl; 27 return 0; 28 } 29 } 30 cout<<m<<" "<<"drawn!"<<endl; 31 return 0; 32 }
No matter how you feel, get up , dress up , show up ,and never give up.