1. 程式人生 > >51nod1282(最小表示法&&枚舉)

51nod1282(最小表示法&&枚舉)

表示 using pro int 情況 註意 str nbsp html

題目鏈接: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 }
View Code

51nod1282(最小表示法&&枚舉)