USACO section 1.1 C++題解

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-1break;
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

相關文章
相關標籤/搜索