第一题:编程
传送门数组
有 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 }