题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1282
题意:中文题目诶~
思路:指针不可转,刻盘可转,显然,对于两组指针,当且仅当它们所有对应相邻指针间距都相等时是满足题意的;
先得到指针间距,因为刻盘可转,相当于循环数组,可以先求一下最小表示法,然后再两两枚举所有情况,对于最小表示法相同的两组指针,计数加一;
代码:
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 const int MAXN = 1e3 + 10; 6 int a[MAXN][MAXN]; 7 8 void get_min(int n, int m){//最小表示法 9 int i = 0, j = 1 ,k = 0, t; 10 while(i < m && j < m && k < m){ 11 t = a[n][(i + k) % m] - a[n][(j + k) % m]; 12 if (!t) k++; 13 else{ 14 if(t > 0) i += k + 1; 15 else j += k + 1; 16 if (i == j) j++; 17 k = 0; 18 } 19 } 20 a[n][m] = i < j ? i : j; 21 } 22 23 int main(void){ 24 int n, m, p, ans = 0; 25 cin >> n >> m >> p; 26 for(int i = 0; i < n; i++){ 27 for(int j = 0; j < m; j++){ 28 cin >> a[i][j]; 29 } 30 sort(a[i], a[i] + m);//注意给出的数据是未排序的 31 int x = a[i][0]; 32 for(int j = 0; j < m - 1; j++){ 33 a[i][j] = a[i][j + 1] - a[i][j]; 34 } 35 a[i][m - 1] = x - a[i][m - 1] + p;//一开始没注意这里的a[i][0]变了,wa到死... 36 get_min(i, m); 37 int cnt = a[i][m], cc = m; 38 while(cc){ 39 cnt = (cnt + 1) % m; 40 cc--; 41 } 42 } 43 for(int i = 0; i < n; i++){ 44 for(int j = i + 1; j < n; j++){ 45 int cnt = m, cnt1 = a[i][m], cnt2 = a[j][m]; 46 while(a[i][cnt1] == a[j][cnt2] && cnt){ 47 cnt--; 48 cnt1 = (cnt1 + 1) % m; 49 cnt2 = (cnt2 + 1) % m; 50 } 51 if(!cnt) ans++; 52 } 53 } 54 cout << ans << endl; 55 return 0; 56 }