第一題:編程
傳送門數組
有 n 個字符串,每一個字符串都是由 A-J 的大寫字符構成。如今你將每一個字符映射爲一個 0-9 的數字,不一樣字符映射爲不一樣的數字。這樣每一個字符串就能夠看作一個整數,惟一的要求是這些整數必須是正整數且它們的字符串不能有前導零。如今問你怎樣映射字符才能使得這些字符串表示的整數之和最大?測試
每組測試用例僅包含一組數據,每組數據第一行爲一個正整數 n , 接下來有 n 行,每行一個長度不超過 12 且僅包含大寫字母 A-J 的字符串。 n 不大於 50,且至少存在一個字符不是任何字符串的首字母。spa
輸出一個數,表示最大和是多少。.net
2 ABC BCA
1875
題解轉自:code
http://blog.csdn.net/yang20141109/article/details/51284495blog
解析:給大寫字母A~J中的每個字母賦一個權重,按照權重由大到小進行排序,依次把9~0十個數字賦值給排序好的的字母。問題的關鍵就在於咱們如何給字母賦值權重。假如咱們有字符串"ABCD",咱們從低位到高位依次給每一個字母賦值爲1,10,100,1000...等。w(D) = 1,w(C) = 10,w(B) = 100,w(A) = 1000。最後咱們把輸入字符串中的每一個字符的權重相加。好比字符串"ABC"和字符串"BCA"。賦值及求和以下圖所示:
由於字符串映射爲的整數不存在前導零,因此咱們須要作一步特殊的處理,在每一個字符串首位置出現的字符都不能爲零。若是出現這種狀況,咱們須要把不在首部出現的具備最小權值字符提到排好序的數組的首部。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 6 using namespace std; 7 8 #define N 55 9 #define M 30 10 #define ll long long 11 12 char s[N][M]; 13 int flag[M]; 14 int le[N]; 15 int n; 16 ll ma; 17 18 struct PP{ 19 ll quan; 20 ll ch; 21 }X[N],te; 22 23 bool cmp(PP a,PP b){ 24 return a.quan < b.quan; 25 } 26 27 void ini(){ 28 int i,j; 29 memset(flag,0,sizeof(flag)); 30 memset(X,0,sizeof(X)); 31 ma = 0; 32 for(i = 0;i < n;i++){ 33 scanf("%s",s[i]); 34 le[i] = strlen(s[i]); 35 } 36 ll temp = 1; 37 for(i = 0;i < n;i++){ 38 flag[ s[i][0] - 'A' ] = -1; 39 temp = 1; 40 for(j = le[i] - 1;j >= 0;j--){ 41 X[ s[i][j] - 'A' ].quan += temp; 42 X[ s[i][j] - 'A' ].ch = s[i][j] - 'A'; 43 temp *= 10; 44 } 45 } 46 } 47 48 void solve(){ 49 sort(X,X + 10,cmp); 50 int i; 51 int pos; 52 if(X[0].quan != 0){ 53 for(i = 0;i < 10;i++){ 54 if(flag[ X[i].ch ] == -1){ 55 continue; 56 } 57 else{ 58 pos = i; 59 te = X[i]; 60 break; 61 } 62 } 63 for(i = pos - 1;i >= 0;i--){ 64 X[i+1] = X[i]; 65 } 66 X[0] = te; 67 } 68 for(i = 0;i < 10;i++){ 69 ma += i * X[i].quan; 70 } 71 72 } 73 74 int main(){ 75 while(scanf("%d",&n) != EOF){ 76 ini(); 77 solve(); 78 printf("%lld\n",ma); 79 } 80 }
第二題:排序
有一個由不少木棒構成的集合,每一個木棒有對應的長度,請問可否用集合中的這些木棒以某個順序首尾相連構成一個面積大於 0 的簡單多邊形且全部木棒都要用上,簡單多邊形即不會自交的多邊形。字符串
初始集合是空的,有兩種操做,要麼給集合添加一個長度爲 L 的木棒,要麼刪去集合中已經有的某個木棒。每次操做結束後你都須要告知是否能用集合中的這些木棒構成一個簡單多邊形。get
每組測試用例僅包含一組數據,每組數據第一行爲一個正整數 n 表示操做的數量(1 ≤ n ≤ 50000) , 接下來有n行,每行第一個整數爲操做類型 i (i ∈ {1,2}),第二個整數爲一個長度 L(1 ≤ L ≤ 1,000,000,000)。若是 i=1 表明在集合內插入一個長度爲 L 的木棒,若是 i=2 表明刪去在集合內的一根長度爲 L 的木棒。輸入數據保證刪除時集合中一定存在長度爲 L 的木棒,且任意操做後集合都是非空的。
對於每一次操做結束有一次輸出,若是集合內的木棒能夠構成簡單多邊形,輸出 "Yes" ,不然輸出 "No"。
5 1 1 1 1 1 1 2 1 1 2
No No Yes No No
注意:
multiset<ll>s;
用multiset刪除某個數要用:
s.erase(s.find(y));
用
s.erase(y);
會把相同的數一塊兒刪除
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #include<set> 6 7 using namespace std; 8 9 #define N 50005 10 #define ll long long 11 12 ll sum; 13 ll ma; 14 int n; 15 int sz; 16 17 int main(){ 18 while(scanf("%d",&n) != EOF){ 19 ma = 0; 20 sum = 0; 21 multiset<ll>s; 22 multiset<ll>::iterator it; 23 int i; 24 int x; 25 ll y; 26 for(i = 0;i < n;i++){ 27 scanf("%d%lld",&x,&y); 28 if(x == 1){ 29 s.insert(y); 30 sum += y; 31 } 32 else{ 33 s.erase(s.find(y)); 34 sum -= y; 35 } 36 it = s.end(); 37 it --; 38 ma = *it; 39 sz = s.size(); 40 if(sz >= 3 && (sum - ma) > ma ){ 41 printf("Yes\n"); 42 } 43 else{ 44 printf("No\n"); 45 } 46 } 47 } 48 49 }