题意:
教师有n行m列 一个老师点名
她会点k次 这个人坐在x行y列的位置
点名方法是从1~n 再从n-1~1
问 被点名次数最多的人被点了多少次 被点名次数最少的人被点了多少次 这个人被点了多少次
思路:
我们将从 1~n 再从 n-1~2 设为一个周期
这样每次新开始点第一排都意味着一个周期的开始
那么 我们一个周期就是点 n*m -2*m 次名
减去的是第一排和最后一排少点的次数
用k减去所有的整数周期 最后一个周期模拟一遍就好了
又是一道会爆int的题
原来cerr不影响AC= =
1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a)) 3 #define debug(a) cerr<<#a<<"=="<<a<<endl 4 using namespace std; 5 typedef long long ll; 6 typedef pair<int,int> pii; 7 8 const int maxn=100+10; 9 10 ll seat[maxn][maxn]; 11 12 int main() 13 { 14 ll k,n,m,x,y; 15 cin>>n>>m>>k>>x>>y; 16 if(n==1) 17 {//n==1的情况可以直接算出来 n==2也是可以的 18 printf("%lld %lld %lld ",k/m+(k%m!=0),k/m,k/m+(y<k%m+1)); 19 return 0; 20 } 21 ll turn=2*n*m-2*m;//每个周期点名的次数 22 int dir=1;//点名方向 23 int a=1,b=1,sum=k%turn; 24 ll l=(k/turn); 25 ll maximum=0,minimum=k/turn,he=0; 26 //计算每一个座位被点到的次数 27 for(int i=1;i<=n;i++) 28 { 29 for(int j=1;j<=m;j++) 30 {//最后一排和第一排是其他地方的一半次数 31 if(i==1 || i==n) seat[i][j]=k/turn; 32 else seat[i][j]=k/turn*2; 33 } 34 } 35 while(sum>0) 36 {//模拟最后一次不完整的周期 37 seat[a][b]++; 38 b++; 39 if(b>m) a+=dir,b=1; 40 if(a>n) 41 {//进入了一个周期的后半部分 42 a=n-1; 43 dir=-1; 44 } 45 sum--; 46 } 47 maximum=max(seat[1][1],max(seat[2][1],seat[n-1][1])); 48 //如果dir==-1 代表进入了一个点名周期的后半部分 最小值要+1 49 printf("%lld %lld %lld ",maximum,minimum+(dir==-1),seat[x][y]); 50 return 0; 51 }/* 52 53 100 100 1000000000000000000 100 100 54 55 */