為了准備應聘過程中的機試環節,找了些OJ機試題來做做。看了帖子http://www.cnblogs.com/whc-uestc/p/4733992.html后用自己的方法對三道華為機試題進行了編寫。
題1
#include <iostream> #include <string> #include <vector> using namespace std; int getmax(vector<int> vec, int a, int b) { int max=0; for(int i=a-1;i<=b-1;i++) { if(max<vec[i]) { max=vec[i]; } } return max; } int main(){ //vector<Log> vec; //Log lg; //while(cin>>lg.path>>lg.row){ // writeLog(vec,lg); //} //for(int i=0; i<vec.size(); i++) // cout<<vec[i].path<<" "<<vec[i].row<<" "<<vec[i].count<<endl; //return 0; //string inputstr; //int a; //int b; //char c[3]; //while(cin>>inputstr>>a>>c) //{ // cout<<inputstr<<a<<c<<'/n'<<endl; //}//"cin>>string/int/char"以空格為分隔符跳入下一個">>"輸入操作 //cout<<inputstr<<endl; //cout<<a<<endl; //cout<<c<<endl; //cout<<lg.row<<endl; int N,M,tem; cin>>N>>M; int n=N; int m=M; vector<int> score;//保存分數 while(n--)//輸入分數並保存操作,不清除輸入緩沖區,保證輸入的一列被錄入 { cin>>tem; score.push_back(tem); } char mode; int A,B; vector<int> answer(M);//想對vector直接賦值就得定義大小,如果不定義大小,直接賦值會出錯,只能用push_back int i=0;//答案下標 while(m--) { cin.sync();//清空cin輸入緩沖區,1.保證輸入的是當前輸入行的數據;2. 保證每次輸入的是一行中的數據 cin>>mode>>A>>B; if(mode=='Q') answer[i++]=getmax(score,A,B); else score[A-1]=B;//將第A個ID改為B } for(int j=0;j<i;j++) cout<<answer[j]<<endl; } //樣例輸入: //5 6 //1 2 3 4 5 //Q 1 5 //U 3 6 //Q 3 4 //Q 4 5 //U 2 9 //Q 1 5
題2
#include <iostream> #include <string> #include <vector> using namespace std; struct Log { string name; int row; int times; }; string getname(string &addrandname) { string name; int N=addrandname.size(),num=1; while(addrandname[N-num]!='\\'&&num!=17)//跳出循環條件,遇到\或第17次循環 { num++; } name=addrandname.substr(N-num+1,num-1); return name; } void savelog(vector<Log> &vec_log, Log log) { int N=vec_log.size(),flag=0; for(int i=0;i<N;i++) { if(vec_log[i].name==log.name&&vec_log[i].row==log.row) { vec_log[i].times++; flag=1; } } if(flag==0) { vec_log.push_back(log); } } void prin(vector<Log> vec_log) { int N=vec_log.size(); for(int i=0;i<N;i++) { cout<<vec_log[i].name<<" "<<vec_log[i].row<<" "<<vec_log[i].times<<endl; } } int main() { string addrandname; int row; cin.sync();//清除輸入緩沖區中的數據流 cin.clear();// 將流中的所有狀態值都重設為有效值 vector<Log> vec_log; Log log; while(cin>>addrandname>>row) { log.name=getname(addrandname); log.row=row; log.times=1; savelog(vec_log,log); prin(vec_log); cin.sync(); cin.clear(); } //string name,aa="123456789123456789.c"; //name=getname(aa); //cout<<name<<endl; //addrandname="aaaa"; //addrandname="fie"; //cout<<addrandname<<endl; }
題3
#include<iostream> #include<string> #include<vector>//vector完全可以替代數組,以后數組用vector,字符串用string,char、int、double只用於單個變量 using namespace std; //單張1 對子3 三個5 順子9 四個7 對王11 //首先判斷是否存在一對王 //判斷是否存在四個 //剩下的比較第一張牌大小 //難點:string類的使用,比較,賦值,長度等 //單張牌大小的比較 bool is2joker(string str)//判斷是否為一對王 { string joker2="joker JOKER",joker21="JOKER joker"; if(str==joker2|str==joker21)//怎么比較兩個string return true; return false; } bool isquar(string str)//判斷是否為四個一樣的牌 { if(str.size()==7) if(str[0]==str[6]) return true; return false; } int pai2num(string str_01) { int re; if(str_01=="jo") re=16; else if(str_01=="JO") re=17; else { switch(str_01[0]) { case '3':re=3;break; case '4':re=4;break; case '5':re=5;break; case '6':re=6;break; case '7':re=7;break; case '8':re=8;break; case '9':re=9;break; case '10':re=10;break; case 'j':re=11;break; case 'q':re=12;break; case 'k':re=13;break; case 'a':re=14;break; case 'J':re=11;break; case 'Q':re=12;break; case 'K':re=13;break; case 'A':re=14;break; case '2':re=15;break; default:re=0;break; } } return re; } bool isbig(string str1,string str2)//判斷牌面值的大小 { return pai2num(str1.substr(0,2))>pai2num(str2.substr(0,2))?true:false; } void main() { string str;//這樣的string類型只能由getline(cin,str)全局函數賦值 //char 類型的向量只能由cin.get(str,size)或cin.getline()賦值 string str1; string str2; getline(cin,str);//getline(cin,str,'/n')和cin.getline(char[],size)區別 int loc=0; int loc1=0; int loc2=0; int flag1=0;//是否遇到- cout<<str.size()<<endl; for(loc;loc<str.size();loc++) { //用什么方法在string后加入字符?如下 //str1+=str[loc];//為什么不能用str1.append(str[loc])或str1.push_back(),因為參數必須為string類型,而不能是char類型 //cout<<str1<<endl; //string類型的用法? //賦值時用用“”括起來的內容,有+=,append(),insert()方法 //string類型不能用於switch(case 只能用於數值和單個字符‘’的內容比較),一般用if() else if()代替(if和elseif只執行一條,前面的優先級高) if(str[loc]=='-') { flag1=1; loc++; } if(flag1==0) str1+=str[loc]; else str2+=str[loc]; } cout<<"一手牌為:"<<str1<<endl; cout<<"另一手牌為:"<<str2<<endl; if(is2joker(str1)|is2joker(str2))//是否有一對王 { string bigone; bigone=is2joker(str1)?str1:str2; cout<<"最大的手牌為:"<<bigone<<endl; } else if(isquar(str1)^isquar(str2))//是否其中一手為四張同樣的牌 { string bigone; bigone=isquar(str1)?str1:str2; cout<<"最大的手牌為:"<<bigone<<endl; } else if(str1.size()==str2.size())//直接比第一張牌的大小即可 { string bigone; bigone=isbig(str1,str2)?str1:str2; cout<<"最大的手牌為:"<<bigone<<endl; } else cout<<"ERROR"<<endl; }
筆記:
1.OJ系統中的題目要求輸入樣例為一行或多行時,怎么考慮輸入過程?
因為OJ系統的輸入樣例和輸出樣例是一一對應的,每輸入一行樣例就進行處理和輸入n行樣例再進行統一處理不會影響評判結果。在不明確輸入樣例具體為幾行時,一般用while(getline(cin,str)){}或者while(cin>>str1>>str2){}語句對每一行數據分別進行處理和輸出;當知道輸入樣例的行數時(一個樣例分為了幾行數據),一般用while(N--){cin>>str1>>str2}語句連續記錄N行輸入數據后再進行處理。
2.回顧了vector,string,getline(),cin.getline(),cin.get(),cin>>相關的知識
vector:創建vector時若不規定大小(默認為空),需用push_back()進行”賦值“;創建時若規定了大小,可用[]和=進行指定位置的賦值。vector<>::iterator it; it可看做一個廣義指針,指向容器中的元素;而vector<>* p2v;是指向容器的指針,p2v->el。
string:完全可以代替字符數組char ch[]。一種特殊的字符容器(比單純的字符容器更強大),可看作普通數據類型,能進行+(拼接)、=(賦值)、==(判斷是否相等)等操作,一般用cin>>str和getline(cin,str)方式賦值。注:cin>>可對string和char數組進行賦值;getline()只用於對string賦值;cin.get()和cin.getline()只用於對char數組進行賦值。
getline()與cin.getline()不同之處在於,前者可以規定文件結束符(默認為‘\n’),且它們是不同的概念,前者屬於istream,后者屬於cin流。注意:getline()在vc6下需要多打一個回車才能確定賦值(第一個回車是結束符,第二回車是輸入結束標志?),而在vs下只需一個回車符。
cin.get():雖然可用於獲得字符串,但一般用於取一個字符(任何字符)。
cin>>:以‘ ’為分隔符,‘\n’為結束符。一次>>到分隔符為至,剩余字符保存在緩沖區中,可用於下一個>>操作。為了避免誤操作,一般用cin.clear()和cin.sync()恢復cin狀態和清空緩沖區。