维护x和y的min和max即可
//浙大2010:题目1020:最小长方形 //给定一系列2维平面点的坐标(x, y),其中x和y均为整数 //要求用一个最小的长方形框将所有点框在内。 //长方形框的边分别平行于x和y坐标轴,点落在边上也算是被框在内。 //其中|x|和|y|小于 231;一对0 坐标标志着一个测试用例的结束 #include <fstream> #include <iostream> using namespace std; int main() { //int i, j, k, m, n; int x, y, left, right, up, down, count; ifstream cin("ZJU_1020.txt");// bool end = 0; while(1){ count = 0; while( cin >> x >> y ){ if( !count ){ if( x==0 & y==0 ) { end = 1; break; } else{ //读入第一个点时 给四向赋值 left = right = x; up = down = y; } } count++; if( x==0 && y==0 ) break; left = min(x,left); right = max(x,right); up = max(y,up); down = min(y,down); } if( end ) break; cout << left << " " << down << " " << right << " " << up << endl; } system("pause");// return 0; }
//浙大2010:题目1021:统计字符 //统计一个给定字符串中指定的字符出现的次数 //第1行为一个长度不超过5的字符串,第2行为一个长度不超过80的字符串 //注意这里的字符串包含空格,即空格也可能是要求被统计的字符之一 //当读到'#'时输入结束,相应的结果不要输出 #include <fstream> #include <string> #include <iostream> using namespace std; int main() { int i, j, k, m, n; string s, t; int a[5], slen, tlen; ifstream cin("ZJU_1021.txt");// while( getline(cin,s) ){ if( s == "#" ) break; getline(cin,t); slen = s.length(); tlen = t.length(); memset(a,0,sizeof(a)); for( i=0; i<tlen; i++ ){ for( j=0; j<slen; j++ ) if( t[i]==s[j] ) { a[j]++; break; } } for( i=0; i<slen; i++ ) cout << s[i] << " " << a[i] << endl; } system("pause");// return 0; }
一个需要注意的细节 只用bool标记穿是否被租过是不行的 因为0标记未租 1标记有E输入 还应有个状态2标记成功退回
//浙大2010:题目1022:游船出租 //当管理员将0作为船号输入时,表示一天租船工作结束 //系统应输出当天的游客租船次数和平均租船时间。 //input: 船号(1~100) 键值(S或E) 发生时间(小时:分钟) //-1表示全部输入结束 #include <fstream> #include <memory.h> #include <string> #include <iostream> using namespace std; struct BOAT{ int start, end; int duration; }boat[100]; int rent[100]; int getTime( string s ){ return ((s[0]-'0')*10+s[1]-'0')*60 + (s[3]-'0')*10+s[4]-'0'; } int main() { int i, j, k, m, n; char status; string t; ifstream cin("ZJU_1022.txt");// memset(rent,0,sizeof(rent)); while( cin >> n >> status >> t && n!=-1 ){ if( n-- ){ //n--以便匹配boat[100]的下标 if( rent[n]==1 && status=='S' || rent[n]==0 && status=='E' ) //排除错误输入 continue; if( status=='S' ){ rent[n] = 1; boat[n].start = getTime(t); } else{ rent[n] = 2; boat[n].end = getTime(t); boat[n].duration = boat[n].end - boat[n].start; } }else{ //n==0 int total=0, num=0, average; for( i=0; i<100; i++ ){ if( rent[i]==2 ){ //cout << "->" << i+1 << endl; num++; total += boat[i].duration; } } if( !num ) cout << "0 0\n"; else{ average = total/num; if( 1.0*total/num >= 0.5+average ) average++; cout << num << " " << average << endl; } memset(rent,0,sizeof(rent)); } } system("pause");// return 0; }
跟清华06年上机题1061是基本一致的 算是浙大抄袭清华?网上是该有回忆版的
//浙大2010:题目1023:EXCEL排序 //每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、 //姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成 //当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序; //当 C=3时,按成绩的非递减排序。 //当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。 #include <fstream> #include <algorithm> #include <cstring> #include <cstdio> #include <iostream> using namespace std; struct STUDENT{ char id[7], name[9]; int score; }t[100005]; bool cmp1( STUDENT x, STUDENT y ){ return strcmp(x.id,y.id)<0; } bool cmp2( STUDENT x, STUDENT y ){ if( strcmp(x.name,y.name)==0 ) return strcmp(x.id,y.id)<0; return strcmp(x.name,y.name)<0; } bool cmp3( STUDENT x, STUDENT y ){ if( x.score == y.score ) return strcmp(x.id,y.id)<0; return x.score < y.score; } int main() { //int i, j, k, m, n; int i, c, n, cases=0; freopen("ZJU_1023.txt","r",stdin);// while( scanf("%d%d",&n,&c)==2 && n ){ cases++; for( i=0; i<n; i++ ) scanf("%s%s%d",t[i].id,t[i].name,&t[i].score);//string不加& if( c==1 ) sort(t,t+n,cmp1); else if( c==2 ) sort(t,t+n,cmp2); else sort(t,t+n,cmp3); printf("Case %d:\n",cases); for( i=0; i<n; i++ ) printf("%s %s %d\n",t[i].id,t[i].name,t[i].score); } while(1);// return 0; }
又见01背包问题 不过有所变形 因为输入数据不是整数 需要先转成整数再处理
//浙大2010:题目1025:最大报销额 //允许报销的发票类型包括买图书(A类)、文具(B类)、差旅(C类), //要求每张发票的总额不得超过1000元 每张发票上,单项物品的价值不得超过600元 //在给出的一堆发票中找出可以报销的、不超过给定额度的最大报销额。 //第1行包含两个正数 Q 和 N,其中 Q 是给定的报销额度,N(N<=30)是发票张数。 //随后是 N 行输入,每行的格式为: // m Type_1:price_1 Type_2:price_2 ... Type_m:price_m //正整数m是物品的件数,Type_i和price_i是第i项物品的种类和价值。 //物品种类用一个大写英文字母表示。 //output: 可以报销的最大数额 精确到小数点后2位 #include <fstream> #include <memory.h> #include <iostream> using namespace std; int invoice[32]; int dp[3000002]; int main() { int i, j, k, m, n; double A, B, C, total, Q, P, result; char c, d;//读入时可以不需转换直接读float bool valid; cout.setf(ios::fixed); cout.setf(ios::showpoint); cout.precision(2); ifstream cin("ZJU_1025.txt");// while( cin >> Q >> n && n!=0 ){ k = 0; for( i=0; i<n; i++ ){ cin >> m; valid = 1; A = B = C = 0; for( j=0; j<m; j++ ){ cin >> c >> d >> P; //P=price switch( c ){ case 'A': A += P; break; case 'B': B += P; break; case 'C': C += P; break; default: valid = 0; //break; } }//m项输入处理 if( valid && A<=600 && B<=600 && C<=600 ){ total = A+B+C; if( total<=1000 && total<=Q ) invoice[k++] = total*100; } } //for( i=0; i<k; i++ ) //k=有效发票数 // cout << invoice[i] << endl; int q = Q*100; memset(dp,0,sizeof(dp)); for( i=0; i<k; i++ ) for( j=q; j>=invoice[i]; j-- ) dp[j] = max(dp[j],dp[j-invoice[i]]+invoice[i]); cout << dp[q]/100.0 << endl; } system("pause");// return 0; }