微軟2程式設計之美2015資格賽

OpenSoucre發表於2015-04-19

證明過程參考程式設計之美2015資格賽題解

題目1 :2月19日

時間限制:2000ms
單點時限:1000ms
記憶體限制:256MB

描述

給定兩個日期,計算這兩個日期之間有多少個2月29日(包括起始日期)。

只有閏年有2月29日,滿足以下一個條件的年份為閏年:

1. 年份能被4整除但不能被100整除

2. 年份能被400整除

輸入

第一行為一個整數T,表示資料組數。

之後每組資料包含兩行。每一行格式為"month day, year",表示一個日期。month為{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"}中的一個字串。day與year為兩個數字。

資料保證給定的日期合法且第一個日期早於或等於第二個日期。

輸出

對於每組資料輸出一行,形如"Case #X: Y"。X為資料組數,從1開始,Y為答案。

資料範圍

1 ≤ T ≤ 550

小資料:

2000 ≤ year ≤ 3000

大資料:

2000 ≤ year ≤ 2×109

樣例輸入
4
January 12, 2012
March 19, 2012
August 12, 2899
August 12, 2901
August 12, 2000
August 12, 2005
February 29, 2004
February 29, 2012
樣例輸出
Case #1: 1
Case #2: 0
Case #3: 1
Case #4: 3

 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 
 8 string MONTHS[12]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November" , "December"};
 9 
10 int getMonth(string mon){
11     for(int i = 0; i <  12; ++ i){
12         if(mon == MONTHS[i]) return i+1;
13     }
14     return 0;
15 }
16 
17 bool judgeLeapYear(int year){
18     if( (year%4 == 0) && (year%100!=0) || (year%400 == 0)) return true;
19     else return false;
20 
21 }
22 
23 int main(){
24     int T;
25     cin >> T;
26     string dot;
27     for( int icase = 1; icase <= T; ++ icase ){
28         string monthStr;
29         int startDay,startYear;
30         cin >>monthStr>>startDay>>dot>>startYear;
31         int startMonth = getMonth(monthStr);
32         int endDay,endYear;
33         cin >> monthStr >> endDay >> dot>>endYear;
34         int endMonth = getMonth(monthStr);
35         int result= 0;
36         for(int i = startYear+1; i <= endYear-1; ++ i){
37             if(judgeLeapYear(i)) result++;
38         }
39         if(startYear==endYear){
40             if(judgeLeapYear(startYear) && startMonth <=2 &&  (endMonth >= 3 || (endMonth == 2 && endDay == 29))) result++;
41         }else{
42             if(judgeLeapYear(startYear) && startMonth <= 2) result++;
43             if(judgeLeapYear(endYear) && (endMonth >= 3 || (endMonth == 2 && endDay == 29))) result++;
44         }
45         cout<<"Case #"<<icase<<": "<<result<<endl;
46     }
47 
48 }

 

題目2 : 迴文字元序列

時間限制:2000ms
單點時限:1000ms
記憶體限制:256MB

描述

給定字串,求它的迴文子序列個數。迴文子序列反轉字元順序後仍然與原序列相同。例如字串aba中,迴文子序列為"a", "a", "aa", "b", "aba",共5個。內容相同位置不同的子序列算不同的子序列。

輸入

第一行一個整數T,表示資料組數。之後是T組資料,每組資料為一行字串。

輸出

對於每組資料輸出一行,格式為"Case #X: Y",X代表資料編號(從1開始),Y為答案。答案對100007取模。

資料範圍

1 ≤ T ≤ 30

小資料

字串長度 ≤ 25

大資料

字串長度 ≤ 1000

 

樣例輸入
5
aba
abcbaddabcba
12111112351121
ccccccc
fdadfa
樣例輸出
Case #1: 5
Case #2: 277
Case #3: 1333
Case #4: 127
Case #5: 17


 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <cstdlib>
 6 #include <cstring>
 7 #include <cstdio>
 8 
 9 #define MOD 100007
10 
11 using namespace std;
12 
13 int main(){
14     int T;
15     cin >> T;
16     for(int icase = 1; icase <= T; ++ icase){
17         string str;
18         cin >> str;
19         int dp[1005][1005]={0};
20         memset(dp,0,sizeof(dp));
21         for(int i = 0 ; i < str.length(); ++ i) dp[i][i] = 1;
22         for(int i = 1; i < str.length(); ++ i){
23             for(int j = i-1; j >=0; -- j){
24                 dp[j][i]=(dp[j+1][i]+dp[j][i-1]-dp[j+1][i-1]+MOD)%MOD;
25                 if(str[i]==str[j])
26                     dp[j][i]=(dp[j][i]+dp[j+1][i-1]+1+MOD)%MOD;
27             }
28         }
29         cout<<"Case #"<<icase<<": "<<dp[0][str.length()-1]<<endl;
30     }
31 
32 }

 

題目3 : 基站選址

時間限制:2000ms
單點時限:1000ms
記憶體限制:256MB

描述

需要在一個N × M的網格中建立一個通訊基站,通訊基站僅必須建立在格點上。

網格中有A個使用者,每個使用者的通訊代價是使用者到基站歐幾里得距離的平方。

網格中還有B個通訊公司,維護基站的代價是基站到最近的一個通訊公司的路程(路程定義為曼哈頓距離)。

在網格中建立基站的總代價是使用者通訊代價的總和加上維護基站的代價,最小總代價。

輸入

第一行為一個整數T,表示資料組數。

每組資料第一行為四個整數:N, M, A, B。

接下來的A+B行每行兩個整數x, y,代表一個座標,前A行表示各使用者的座標,後B行表示各通訊公司的座標。

輸出

對於每組資料輸出一行"Case #X: Y",X代表資料編號(從1開始),Y代表所求最小代價。

資料範圍

1 ≤ T ≤ 20

1 ≤ x ≤ N

1 ≤ y ≤ M

1 ≤ B ≤ 100

小資料

1 ≤ N, M ≤ 100

1 ≤ A ≤ 100

大資料

1 ≤ N, M ≤ 107

1 ≤ A ≤ 1000

樣例輸入
2
3 3 4 1
1 2
2 1
2 3
3 2
2 2
4 4 4 2
1 2
2 4
3 1
4 3
1 4
1 3
樣例輸出
Case #1: 4
Case #2: 13
 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 
 8 using namespace std;
 9 
10 int dx[4]={0,0,1,1};
11 int dy[4]={0,1,0,1};
12 
13 int main(){
14     int T;
15     cin >> T;
16     for(int icase = 1; icase <= T; ++ icase){
17         long long N,M,A,B;
18         cin >>N>>M>>A>>B;
19         vector<long long> a_x(A,0), a_y(A,0);
20         vector<long long> b_x(B,0), b_y(B,0);
21         for(int i = 0 ; i  < A; ++ i )  cin >> a_x[i]>>a_y[i];
22         for(int i = 0 ; i <  B; ++ i) cin >> b_x[i] >> b_y[i];
23         long long sum_a_x_2 = 0, sum_a_x = 0, sum_a_y = 0, sum_a_y_2 = 0;
24         for(int i = 0 ; i < A ; ++ i){
25             sum_a_x_2+=a_x[i]*a_x[i];
26             sum_a_x +=a_x[i];
27 
28             sum_a_y +=a_y[i];
29             sum_a_y_2+=a_y[i]*a_y[i];
30         }
31         long long x = sum_a_x/A, y=sum_a_y/A, ans = LLONG_MAX;
32         for(int i = 0 ; i < 4; ++ i){
33             long long curx = x + dx[i], cury = y+dy[i],dist = LLONG_MAX;
34             long long curResult = sum_a_x_2 + A*curx*curx-2*curx*sum_a_x + sum_a_y_2 + A*cury*cury - 2*cury*sum_a_y;
35             for(int j = 0 ; j < B; ++ j){
36                 dist = min(dist,abs(curx-b_x[j])+abs(cury-b_y[j]));
37             }
38             ans = min(ans,curResult+dist);
39         }
40         cout<<"Case #"<<icase<<": "<<ans<<endl;
41     }
42 
43 }

 




 
 

相關文章