USACO section1.1:
DONE 2017.03.03 TEXT Submitting Solutions
DONE 2017.03.04 PROB Your Ride Is Here [ANALYSIS]
DONE 2017.03.04 TEXT Contest Problem Types
DONE 2017.03.04 TEXT Ad Hoc Problems
DONE 2017.03.04 PROB Greedy Gift Givers [ANALYSIS]
DONE 2017.03.04 PROB Friday the Thirteenth [ANALYSIS]
DONE 2017.03.04 PROB Broken Necklace [ANALYSIS]
由上可見section1.1中共有四道題,沒有考察算法,只是單純看思考是否到位以及細心程度。ios
Prob1:Your Ride Is Here(水題)
題意:input給出兩個所有由大寫字母組成的單詞, 每一個字母對應一個數字(A-1,B-2……),
兩個單詞中的字母分別相乘,獲得兩個數字, 判斷這兩個數字%47的餘數是否相等。算法
NOTE:因爲數據很小,無須擔憂溢出,可是保險起見,仍是在每次運算的過程當中取餘。(a%b)*(c%b) = (a*c)%b;數組
源代碼:ide
1 /* 2 ID:kongse_1 3 PROG:ride 4 LANG:C++ 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int MOD = 47; 11 string a, b; 12 int num1=1 ,num2=1; 13 int main() 14 { 15 freopen("ride.in", "r", stdin); 16 freopen("ride.out", "w", stdout); 17 cin >> a >> b; 18 19 for(int i = 0; i != a.size(); ++i) 20 num1 = (num1*(a[i]-'A'+1))%MOD; 21 for(int i = 0; i != b.size(); ++i) 22 num2 = (num2*(b[i]-'A'+1))%MOD; 23 24 if(num1 == num2) cout << "GO" << endl; 25 else cout << "STAY" << endl; 26 fclose(stdin); 27 fclose(stdout); 28 return 0; 29 }
Prob2:Greedy Gift Givers (水題)
題意:有n我的,沒人開始身上有0塊錢,每一個人選擇掏出x的錢給他指定的n我的買禮物,他指定的人每一個人獲得x/n塊錢,若除不盡(x%n)則多出來的零錢歸他本身。輸出一輪以後每一個人對應的錢數(能夠是負的...)。spa
P.S:原本開始想要用map作一一映射,結果map自帶排序,把原來輸入的順序搞沒了,因而乎只能拿倆數組維護。code
源代碼:blog
1 /* 2 ID:kongse_1 3 PROG:gift1 4 LANG:C++ 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <algorithm> 9 #include <cstring> 10 using namespace std; 11 const int maxn = 15; 12 string x[maxn], y[maxn], z; 13 int num, sum, n, money[maxn]; 14 int find_(string curr) 15 { 16 for(int i = 0; i != num; ++i) 17 { 18 if(x[i] == curr) return i; 19 } 20 } 21 void calculate_(int a, int b) 22 { 23 money[a] -= b; 24 return ; 25 } 26 int main(){ 27 freopen("gift1.in", "r", stdin); 28 freopen("gift1.out", "w", stdout); 29 30 cin >> num; 31 32 for(int i = 0; i != num; ++i) 33 { 34 cin >> x[i]; 35 } 36 37 for(int i = 0; i != num; ++i) 38 { 39 cin >> z >> sum >> n; 40 if(n) 41 { 42 calculate_(find_(z), sum-sum%n); 43 for(int j = 0; j != n; ++j) 44 { 45 cin >> y[j]; 46 calculate_(find_(y[j]), -sum/n); 47 } 48 } 49 } 50 51 for(int i = 0; i != num; ++i) 52 { 53 cout << x[i] << " " << money[i] << endl; 54 } 55 fclose(stdin); 56 fclose(stdout); 57 return 0; 58 }
Prob3:Friday the Thirteenth
題意:已知1900年1月1日是週一,統計包括1900年在內的N年間,每個月13號是週一——週日的次數。排序
NOTE1:獲得1900年1月13日是週六,根據每月的天數算出下一個月13日是星期幾,注意判斷閏年便可。隊列
NOTE2:若是按照每一年做爲單位一步步求,會出現一個問題:每年算的第12次實際上算的是下一年的1月13日(+31便是度過了12月份到了一月),因此算的最後一年的循環要特判。
源代碼:ci
1 /* 2 ID:kongse_1 3 PROG:friday 4 LANG:C++ 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 using namespace std; 10 const int maxn = 15; 11 int month[maxn]={0,31,28,31,30,31,30,31,31,30,31,30,31}, N, times[maxn], curr = 6; 12 int whether(int year) 13 { 14 if(year%400 == 0 || (year%4 == 0 && year%100 != 0)) return 1; 15 return 0; 16 } 17 void caculate_(int year) 18 { 19 if(year == 1900+N) return ; 20 21 if(whether(year)) month[2] = 29; 22 else month[2] = 28; 23 24 for(int i = 1; i != 13; ++i) 25 { 26 curr = (curr+month[i])%7; 27 if(i == 12 && year == 1900+N-1) break; 28 ++times[curr]; 29 } 30 caculate_(year+1); 31 } 32 int main() 33 { 34 freopen("friday.in", "r", stdin); 35 freopen("friday.out", "w", stdout); 36 37 cin >> N; 38 39 ++times[6]; 40 caculate_(1900); 41 42 cout << times[6] << " "; 43 for(int i = 0; i != 6; ++i) 44 { 45 cout << times[i]; 46 if(i != 5) cout << " "; 47 } 48 cout << endl; 49 50 fclose(stdin); 51 fclose(stdout); 52 return 0; 53 }
Prob4:Broken Necklace(有點意思)
題意:一串項鍊有三種顏色:紅(r),藍(b),白(w)。從中間某一處斷開,從斷開的兩邊分別去從頭取顏色相同的珠子(兩邊右的可摘取數,而後從兩個序列中找到a[i]+b[i+1]最大值(由於是從中間斷的兩川,因此必定是相鄰的且向左的是第i個,向右的是第(i+1)%n)個。(注意,這是一串項鍊,首尾相連,是個循環隊列)。
而算出沒一個的向左區和向右取的值也很簡單,不須要每一個都算,例如算出第i個能夠向左取m個,那麼第(i-1)個,即他的左邊必定只能取(m-1)個(m!=1),m = 1即只有本身。當出現左邊的顏色與當前顏色不一樣時再從新計算。可是有一個例外。
咱們觀察這樣的一串:bbwbwrrwrwr 第一個b是5,第五個w則應該是1,可是事實上第五個應該是7,由於它跟右邊的紅色也能夠相連。因此咱們獲得特判:當上一個是2而且當前是白色(w)時應從新計算(即w是某隊隊尾)。
源代碼:
1 /* 2 ID:kongse_1 3 PROG:beads 4 LANG:C++ 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <cstdlib> 11 using namespace std; 12 const int maxn = 505; 13 string x; 14 int n, num[2][maxn], max_; 15 int whether(char a, char b) 16 { 17 if(a+b == 'r'+'b') return 1; 18 return 0; 19 } 20 void calculate_(int curr, string y) 21 { 22 char last = x[curr]; 23 if(y == "left") 24 { 25 int wh = 1; 26 num[wh][curr] = 1; 27 for(int i = (curr-1+n)%n;i != curr ; i = (i-1+n)%n) 28 { 29 if(x[i] == last || x[i] == 'w' || last == 'w') 30 { 31 if(last == 'w') last = x[i]; 32 ++num[wh][curr]; 33 } 34 else break; 35 } 36 } 37 38 else 39 { 40 int wh = 0; 41 num[wh][curr] = 1; 42 for(int i = (curr+1)%n; i != curr ; i = (i+1+n)%n) 43 { 44 if(x[i] == last || x[i] == 'w' || last == 'w') 45 { 46 if(last == 'w') last = x[i]; 47 ++num[wh][curr]; 48 } 49 else break; 50 } 51 } 52 return ; 53 } 54 int main() 55 { 56 freopen("beads.in", "r", stdin); 57 freopen("beads.out", "w", stdout); 58 59 cin >> n >> x; 60 61 for(int i = 0; i != n; ++i) 62 { 63 if( !i || (num[0][(i-1+n)%n] == 2 && x[i] == 'w') || whether(x[(i-1+n)%n],x[i]) ) 64 calculate_(i, "right"); 65 else num[0][i] = num[0][i-1]-1; 66 } 67 68 for(int i = n-1; i != -1; --i) 69 { 70 if( i == n-1 || (num[1][(i+1)%n] == 2 && x[i] == 'w') || whether(x[(i+1)%n],x[i]) ) 71 calculate_(i, "left"); 72 else num[1][i] = num[1][i+1]-1; 73 } 74 75 for(int i = 0; i != n; ++i){ 76 77 max_ = max(max_, num[0][i]+num[1][(i-1+n)%n] ); 78 } 79 80 cout <<((max_<n)?max_:n) << endl; 81 82 fclose(stdin); 83 fclose(stdout); 84 85 return 0; 86 }
自此,USACO section1.1便所有完成了。
箜瑟_qi 2016.03.04