题意:n行m列人,老师点k次名。点名次序,每一行都是从1到m,但行是按1,2....(n-1),n,(n-1),(n-2)...1,2,3....(n-1),n.....求点完k次名后被点的最多的次数和最少的次数,以及给定的(x,y)被点次数。
总结:有点麻烦,但还是很好找规律,只是fst了,有时间再写一遍。。。还是太菜了,连着三场CF都是fst
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define F(i,a,b) for (int i=a;i<b;i++) #define FF(i,a,b) for (int i=a;i<=b;i++) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 1e5+10; const ll inf = 1.5e18; int main() { int n, m, x, y; ll k, a[150][150]; while(cin>>n>>m>>k>>x>>y) { mes(a,0); ll num; if(n==1) { num= k/m, k%=m; FF(j,1,m) a[1][j]=num; FF(j,1,m) { if(k==0) break; k--, a[1][j]++; } } else { FF(j,1,m) { if(k==0) break; k--; a[1][j]++; } num= k/ ((n-1)*m ); k%= (n-1)*m; if(num&1) { FF(i,1,n) FF(j,1,m) { if(i==1) a[i][j] += (num>>1); else if(i==n) a[i][j] += ((num>>1)+1LL); else a[i][j] += num; } for(int i=n-1; i>=1; i--) { if(k==0) break; FF(j,1,m) { if(k==0) break; k--, a[i][j]++; } } } else { FF(i,1,n) FF(j,1,m) { if(i==1 || i==n) a[i][j]+= (num>>1); else a[i][j]+= num; } FF(i,2,n) { if(k==0) break; FF(j,1,m) { if(k==0) break; k--, a[i][j]++; } } } } ll maxn=-inf, minn=inf, mm; FF(i,1,n) FF(j,1,m) { if(maxn<a[i][j]) maxn=a[i][j]; if(minn>a[i][j]) minn=a[i][j]; if(x==i && y==j) mm=a[i][j]; } cout<<maxn<<" "<<minn<<" "<<mm<<endl; } return 0; } //2 2 6 1 1 //3 5 1 2 1