【ACM知識點(一)】ACM中常用的輸入輸出方式


  不論是在ACM/ICPC這樣類型的比賽中,還是在做項目中,對於輸入輸出的格式尤為重要,不可以想當然的按自己那一套走,我們需要根據題目要求進行操作,對於第一次接觸這方面比賽的小白,最為常見的現象便是類似於下面這行代碼

1 printf(“請輸入一組數據:”); 
2 cout<<"輸出的結果為";

  倘若題目沒有要求你,千萬不要有多余的輸出,雖然在測試的時候方便自己,但也麻煩在提交運行時注釋掉,因為電腦可沒有你的大腦那樣靈活,他要對比的數據很死板,多一個空格少一個空格都不行,所以,在這一塊的處理一定要細心!細心!再細心! 下面我們來看下常見的輸入輸出格式有哪些

一、基本輸入輸出

1、單組輸入輸出

已知題目有兩個變量a和b,現在就要輸入a和b,操作如下

 

1 //C
2 scanf("%d %d",&a,&b); printf("%d %d\n",a,b);
3 //C++
4 cin>>a>>b; cout<<a<<b<<endl;

 

這個很簡單,那么如果題目輸入n組a和b怎么辦呢

2、n組輸入輸出

1 //C
2 scanf("%d",&n);
3 while(n--) {scanf("%d %d",&a,&b); printf("%d %d\n",a,b);}
4 //C++
5 cin>>n;
6 while(n--){cin>>a>>b;cout<<a<<b<<endl;}

也沒有那么難嘛,現在如果n不告訴你,要求輸入多組a和b該如何操作呢?

3、多組輸入輸出(重點來了!!!)

1 //C
2 while(scanf("%d %d",&a,&b)!=EOF){printf("%d %d\n",a,b);}//第一種寫法
3 while(scanf("%d %d",&a,&b)==2){printf("%d %d\n",a,b);}//第二種寫法
4 while(~scanf("%d %d",&a,&b)){printf("%d %d\n",a,b);}//第三種寫法        
5 //C++
6 while(cin>>a>>b){cout<<a<<b<<"\n";}     

競賽中經常采用這種輸入輸出方式。我們來看看上面第二點,輸入n組a和b如何也像這樣的格式進行操作

 1 //C
 2 while(scanf("%d",&n)!=EOF)//第一種寫法
 3 {
 4     while(n--)
 5     {
 6        scanf("%d %d",&a,&b);        
 7        printf("%d %d\n",a,b); 
 8     }
 9 }
10 while(scanf("%d",&n)==1)//第二種寫法
11 {
12     while(n--)
13     {
14        scanf("%d %d",&a,&b);        
15        printf("%d %d\n",a,b); 
16     }
17 }
18 while(~scanf("%d",&n))//第三種寫法        
19 {
20     while(n--)
21     {
22        scanf("%d %d",&a,&b);        
23        printf("%d %d\n",a,b); 
24     }
25 }
26 //C++
27 while(cin>>n)
28 {
29     while(n--)
30     {
31        cin>>a>>b;       
32        cout<<a<<b<<"\n";
33     }
34 }

【敲重點了】有沒有發現,對於多組輸入的a和b,是邊輸入邊輸出,而不是將這些數存到某數組里面,在輸入結束時,再對其進行分別輸出。如果你還是小白,千萬不要忽視這一點,興許你現在還沒不以為然,但一定要有這個思維。請記住,如果輸入的每組數據的結果不相互干擾的話,就可以在本次操作的時候將該組數據的相關結果進行輸出

二、復雜的輸入輸出

1、讀入多行,且每行數據個數不確定

是不是已經對輸入輸出有一點感覺了,那么來考驗下你的C語言基礎。

已知題目,每一行有多個數據(不知道有多少個數),每個數據之間以空格相隔。碰到這種情況怎么做呢,學過C語言都知道一行一行讀入有getline(),也可以一個一個字符讀入的getchar(),而C++中有流的操作,具體操作有以下幾種辦法

 1 //getchar()版本
 2 int fg=0;//用於判斷a中是否存放了數字
 3 int a=0;//每個數據讀入a中
 4 char c=getchar();//一個一個的讀入
 5 while(c!='\n')
 6 {
 7      if(fg==1&&c==' '){printf("%d ",a);a=0;fg=0;continue;}//跳過空格
 8      fg=1;//表示fg中已經存放了數字
 9      a=10*a+c-'0';//將字符轉為整型變量
10 }
11 
12 //getline()版本
13 int fg=0;//用於判斷a中是否存放了數字
14 int a=0;//每個數據讀入a中
15 string ss;
16 while(getline(cin,ss))
17 {
18      int cn=0;
19      while(s[cn]!='\n')
20     {
21         if(fg==1&&s[cn]==' '){printf("%d",a);a=0;fg=0;}//跳過空格
22         else if(ss[cn)!=' '){
23               fg=1;//表示fg中已經存放了數字
24               a=10*a+c-'0';//將字符轉為整型變量
25         }
26          cn++;
27     }
28 }
29 
30 //利用流的操作版本
31 string ss,st;
32 while(getline(cin,str)) {
33         stringstream ss(str); 
34         while(ss>>st) printf("%s",st.c_str());
35 }

是不是有點燒腦了,如果要處理稍微復雜的輸入,則至少需要掌握這方面的一種方法,尤其在碰到整行讀入時可以利用getline(),將每行讀入到字符串中,再對字符串進行相關操作,當然方法不止以上三種,像cin.getline()等都可以進行相關操作

2、文件流的操作

(1)重定向(必須掌握)

1 freopen("1.txt","r",stdin);

掌握了它,在本地測試時可以提前將數據存放在同目錄下的 1.txt(文件名要於freopen()中的文件名一致) 文件中,然后在本地運行時,它將自動讀入數據。記得今年藍橋杯省賽時,有一組數據非常多(有的題目的數據無法拷貝),如果不知道重定向,那么每次本地運行測試時,都要手動輸入,將會浪費很多時間。

(2)文件流的操作(有的題目會有這方面要求)

 1 //C++語法
 2 ifstream fin("in.txt");
 3 ofstream fout("out.txt");
 4 int a,b;
 5 while(fin>>a>>b)  fout<<a+b<<endl;
 6 fin.close();
 7 fout.close();
 8 
 9 //C語法
10 FILE *fin,*fout;
11 int a,b;
12 fin=fopen("in.txt","r");
13 fout=fopen("out.txt","w");
14 while(fscanf(fin,"%d %d",&a, &b) != EOF)
15 fprintf(fout,"%d\n",a+b);
16 fclose(fin);
17 fclose(fout);

 

三、總結輸出格式

1、每個數據間以空格相隔,行末不得有多余的空格

//C++
if(first) first=0;//first判斷是否時每行第一個元素
else cout<<“ ”;
cout<<a;
//C語法
if(first) first=0;
else printf(" ");
printf("%d",a);

 

 HDOJ中相關題目:1000 1089-1096 1001 2081 2057 2031

如果本文有錯誤的地方請指正的哈^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM