非长整数计算 只需字符转数字处理后再运算即可
//浙大2010:题目1003:A+B //input:由两个整数A和B组成(-10^9 < A,B < 10^9)。 #include <fstream> #include <string> #include <iostream> using namespace std; int process( string s ){ int a[9], i, j, start, sign; if( s[0]==45 ) { sign = -1; start = 1; } else { sign = 1; start = 0; } int len = s.length(); for( i=start,j=0; i<len; i++ ) if( s[i]!=',' ) a[j++] = s[i] - 48; int at = a[0]; for( i=1; i<j; i++ ) at = at*10 + a[i]; return at*sign; } int main() { int i, j, k, m, n; string as, bs; int result; //ifstream cin("ZJU_1003.txt");// while( cin >> as >> bs ){ result = process( as ) + process( bs ); cout << result << endl; } //system("pause"); return 0; }
虽然第一眼看去像是DP题 但是有规律可循的 首先z j各一个 其次被z和j分成3段的o的个数满足(i,j,i*j) i>=0 j>=1的关系
//浙大2010:题目1006:ZOJ问题 //AC条件:(i,1,i)->(i,2,2i)->(i,3,3i)->... #include <fstream> #include <string> #include <iostream> using namespace std; int main() { int i, z, oo, j, other; string s; //ifstream cin("ZJU_1006.txt");// while( cin >> s ){ int len = s.length(); int zflag, jflag; z = oo = j = other = 0; for( i=0; i<len; i++ ){ if( s[i]=='z' ){ z++; zflag = i; } else if( s[i]=='o' ) oo++; else if( s[i]=='j' ){ j++; jflag = i; } else other++; } if( other!=0 || z!=1 || j!=1 ){ cout << "Wrong Answer\n"; continue; } int o[3]; o[0] = zflag; o[1] = jflag-zflag-1; o[2] = oo - o[0] - o[1]; if( o[1] == 0 || o[2]!=o[0]*o[1] ) cout << "Wrong Answer\n"; else cout << "Accepted\n"; } //system("pause"); return 0; }
这道题比较综合 难度其实不算大 但一些细节需要注意
首先 要排序的国家是被选择的 这很好理解 因为可能是要亚洲区的排名 此时当然不能输出亚洲每个国家在世界整体范围的排名而应是本洲内的排名 这时就需要把选定的那些国家拼在一起 比如4个国家c[0]~c[3] 要排序0和3 就要把c[3]的数据挪到c[1]上 因为STL的sort或qsort都是要求被排序内容下标连续的
对于挪移这个问题 一种处理的方式是先记录好所有要排序的国家号 再对这个记录进行升序排序 然后一个个挪移 不过这种方法就需要维护两个记录 因为排序会抹杀掉原来输入的记录 而该记录是最后输出结果所需要的[此时认定题目中输入的国家号可能乱序且输出时要按输入的顺序进行] 另一种方法就是编程珠玑第一栏就给出的bitmap方法了 位图排序方法有一定局限性 不过此问题刚好适合 不仅速度更快 也没有上述的缺点
其次 gdp和mdp可以在拼到一起之后再算 这样只需算m次 而在输入n个国家时就算则要算n次
另外 要注意处理平局情况的排名 一个简单策略就是去比对排名小一位的国家的成绩是否和自己相等 若相等则把人家的排名copy到自己身上即可
最后 用for循环4次+switch可以把程序写的相对简洁易读点
test函数是调试用的输出 其他一些被注释掉的调试语句也保留了
//浙大2010:题目1007:奥运排序问题 //input:第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。 //第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。 //接下来一行给出M个国家号。 //output:对每个国家给出最佳排名排名方式 和 最终排名 #include <fstream> #include <memory.h> #include <algorithm> #include <string> #include <iostream> using namespace std; struct COUNTRY{ int gold, medal, population; int index; //保留原始序号 double gdp, mdp; //gdp=gold/population }; #define N 300 COUNTRY c[N]; int mc[N], best[N], bestway[N]; int s[N][4]; //s=sort 记录4种排序的序号情况 bool selected[N]; bool cmp1( const COUNTRY &x, const COUNTRY &y ){ return x.gold > y.gold; } bool cmp2( const COUNTRY &x, const COUNTRY &y ){ return x.medal > y.medal; } bool cmp3( const COUNTRY &x, const COUNTRY &y ){ return x.gdp > y.gdp; } bool cmp4( const COUNTRY &x, const COUNTRY &y ){ return x.mdp > y.mdp; } void chooseBest( int &m ){ int i, j; //for( j=0; j<4; j++ ){ // for( i=0; i<m; i++ ) // cout<<"s[mc["<<i<<"]]["<<j<<"]="<<s[mc[i]][j]<<" "; // cout << endl; //} for( i=0; i<m; i++ ){ best[mc[i]] = min( min(s[mc[i]][0],s[mc[i]][1]), min(s[mc[i]][2],s[mc[i]][3]) ); for( j=0; j<4; j++ ) if( s[mc[i]][j] == best[mc[i]] ){ //保证了相同最佳排名时 取排名方式号最小的 bestway[mc[i]] = j + 1; break; } } for( i=0; i<m; i++ ) cout << best[mc[i]] << ":" << bestway[mc[i]] << endl; cout << endl;// } void test( int m ){ for(int i=0; i<m; i++ ) cout<<c[i].index<<":"<<" "<<c[i].gold<<" " <<c[i].medal<<" "<<c[i].gdp<<" "<<c[i].mdp<<endl; } int main() { int i, j, k, m, n; ifstream cin("ZJU_1007.txt");// while( cin >> n >> m ){ //n个国家 其中m个要排序 memset(selected, 0, sizeof(selected)); for( i=0; i<n; i++ ){ cin >> c[i].gold >> c[i].medal >> c[i].population; c[i].index = i; } for( i=0; i<m; i++ ){ cin >> mc[i]; selected[mc[i]] = 1; } if( m!=n ) for( i=0,j=0; i<n; i++ ) //剃掉不需排队的国家 if( selected[i] ){ //需要排队且和当前欲写入下标不同时才写入 if( i==j ) { j++; continue; } //cout<<i<<" selected\n";// c[j] = c[i];// j++; } for( i=0; i<m; i++ ){ //并不在输入时就算好 因为不需排序的国家不必算 c[i].gdp = (double)c[i].gold/c[i].population; c[i].mdp = (double)c[i].medal/c[i].population; } //cout << "original:\n"; test(m); cout<<endl;// for( j=0; j<4; j++ ){ switch(j){ case 0: sort( c, c+m, cmp1 ); break; case 1: sort( c, c+m, cmp2 ); break; case 2: sort( c, c+m, cmp3 ); break; case 3: sort( c, c+m, cmp4 ); break; } //cout << "mode["<<j<<"]:\n"; test(m); cout<<endl;// s[c[0].index][j] = 1; for( i=1; i<m; i++ ){ s[c[i].index][j] = i+1; //s[2][0]表示2号国家的第一种排名 switch(j) { case 0: if( c[i].gold==c[i-1].gold ) s[c[i].index][j] = s[c[i-1].index][j]; break; case 1: if( c[i].medal==c[i-1].medal ) s[c[i].index][j] = s[c[i-1].index][j]; break; case 2: if( c[i].gdp==c[i-1].gdp ) s[c[i].index][j] = s[c[i-1].index][j]; break; case 3: if( c[i].mdp==c[i-1].mdp ) s[c[i].index][j] = s[c[i-1].index][j]; break; } } }//四重排序for chooseBest(m); } system("pause"); return 0; }
这题WA卡了我半周 百思不得其解 郁闷之极 后来发现 人家要求输出YES我输出的是yes 眼泪都下来了有木有 T_T
多说一句 二叉排序树的中序遍历是一样的 都是所有元素的升序排列 所有判等只需校验先序遍历是否相等即可 因为前序+中序确定一棵二叉树嘛
//浙大2010:题目1009:二叉搜索树 //判断两序列是否为同一二叉搜索树序列 //input:开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束。 //接下去一行是一个序列,序列长度小于10,包含(0~9)的数字,没有重复数字 //接下去的n行有n个序列,请判断它和第一个序列是否能组成同一颗二叉搜索树。 #include <fstream> #include <string> #include <iostream> using namespace std; struct BiTree{ char c; BiTree* l; BiTree* r; }; string inOrder, preOrder; void insertNode( BiTree *Root, char ch ){ BiTree *t = new BiTree(); //新生成节点 t->c = ch; t->l = t->r = NULL; BiTree *p = Root; //查找指针 while( true ){ if( ch < p->c ){ if( p->l!=NULL ) p = p->l; else { p->l = t; break; } } else if( p->r!=NULL ) p = p->r; else { p->r = t; break; } } } BiTree* buildTree( string s ){ BiTree *Root = new BiTree(); //t=tree Root->c = s[0]; Root->l = Root->r = NULL; int len = s.length(); for( int i=1; i<len; i++ ) insertNode( Root, s[i] ); return Root; } void preTraverse( BiTree* t ){ if( t != NULL ){ preOrder += t->c; if( t->l != NULL) preTraverse(t->l); if( t->r != NULL) preTraverse(t->r); } }; int main() { int i, j, k, m, n, len; string a, b, Ain, Apre, Bin, Bpre; ifstream cin("ZJU_1009.txt");// while( cin >> n && n!=0 ){ cin >> a; preOrder = ""; preTraverse( buildTree(a) ); Apre = preOrder; //cout << "Apre=" << Apre << endl; for( i=0; i<n; i++ ){ cin >> b; preOrder = ""; preTraverse( buildTree(b) ); Bpre = preOrder; //cout << "Bpre=" << Bpre << endl; if( Apre == Bpre ) cout << "YES\n"; else cout << "NO\n"; } } system("pause"); return 0; }