9月份考ccf,暑假打算做一些往年的真題。。。
這個題,一開始真是把我給看暈了
傳說中的大模擬,果然不簡單QAQ
首先讀懂題目就是一個大難點,特別是對於我這種題目一長就看不進去的人來說
讀懂題目之后,思路就好想了,下面簡單說一下我的思路:
首先定義一個字符數組ss[N][M],然后用ss[i]存入編號為 i 的硬盤后面的字符串,
在后面處理的時候就可以用sscanf函數直接獲取ss[i]中相應位置的十六進制數(輸入用"%8x",輸出用"%08X")。
再一個比較燒腦的地方就是根據輸入的塊的編號b確定該塊所在的硬盤和條帶編號
條帶編號k=b/s/(n-1); 結合圖從左到右讀這個式子就能想明白
所在硬盤編號t=n-1+k*(n-1)+b/s%(n-1)+1; t%=n; 其中n-1是條帶編號為0對應的校驗盤位置,條帶編號+1,校驗盤-1(等價於+(n-1)); b/s%(n-1)是塊所在硬盤相對校驗盤的偏移量。(這是先前的版本,對的,但是很復雜。。。后來發現其實可以很簡單,直接 t=b/s%n; 就出來了)
一開始我輸入語句是這樣寫的:
1 for(int i=0;i<l;i++){ 2 int x; 3 scanf("%d",&x); 4 scanf("%s",ss[x]); 5 }
然后就是各種超時,哪怕我想方設法優化代碼,怎么搞也只有70分
我就納悶了,這時間復雜度我滿打滿算也不過1e7啊,咋就超時了呢?
百思不得其解,於是毅然百度。。。
然后發現很多幾個題解都是用的很c++風格的代碼,算法復雜度和我沒什么區別,而且用的cin,居然還比scanf快???
於是乎,我發現了一條神奇的代碼
1 ios::sync_with_stdio(false);
據說它可以關閉c++的流同步,防止cin超時
於是乎,我試着把所有的標准輸入換成了cin,加上那句我看不懂的玩意兒,居然還真過了!!!

1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 using namespace std; 5 typedef long long ll; 6 const int M=10240*8+1; 7 const int N=1000; 8 char ss[N][M]; 9 int main() 10 { 11 //freopen("in.txt","r",stdin); 12 ios::sync_with_stdio(false); 13 int n,s,l; 14 cin>>n>>s>>l;//scanf("%d%d%d",&n,&s,&l); 15 for(int i=0;i<l;i++){ 16 int x; 17 cin>>x;//scanf("%d",&x); 18 cin>>ss[x];//scanf("%s",ss[x]); 19 } 20 int m; 21 cin>>m;//scanf("%d",&m); 22 while(m--){ 23 ll b; 24 cin>>b;//scanf("%lld",&b); 25 ll t=n-1+b/s/(n-1)*(n-1)+b/s%(n-1)+1,k=(b/s/(n-1)*s+b%s)*8;t%=n; 26 if(k>=M||ss[t][0]==0&&l<n-1||ss[0][k]==0&&ss[1][k]==0&&ss[t][k]==0){ 27 printf("-\n"); 28 continue; 29 } 30 if(ss[t][0]==0){ 31 ll ans=0; 32 for(int i=0;i<n;i++){ 33 if(i==t)continue; 34 ll x; 35 sscanf(ss[i]+k,"%8x",&x); 36 ans^=x; 37 } 38 printf("%08X\n",ans); 39 } 40 else{ 41 ll ans; 42 sscanf(ss[t]+k,"%8x",&ans); 43 printf("%08X\n",ans); 44 } 45 } 46 return 0; 47 }
但是scanf超時超在哪呢???
直到之后又看到一篇博客,我才知道字符串輸入用scanf會超時,因為最后三組數據40kb的數據長度,意味着一個字符串最多有80kb個字符要輸入,而一次最多有1000個字符串待輸入,輸入數據量賊大
於是改用專門的字符串輸入函數gets或fgets就沒問題了(不過據說gets大勢已去,建議盡量用fgets)
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 using namespace std; 5 typedef long long ll; 6 const int M=10240*8+1; 7 const int N=1000; 8 char ss[N][M]; 9 int main() 10 { 11 //freopen("in.txt","r",stdin); 12 int n,s,l; 13 scanf("%d%d%d",&n,&s,&l); 14 for(int i=0;i<l;i++){ 15 int x; 16 scanf("%d%*c",&x); 17 fgets(ss[x],M,stdin);//gets(ss[x]); 18 } 19 int m; 20 scanf("%d",&m); 21 while(m--){ 22 ll b; 23 scanf("%lld",&b); 24 ll t=b/s%n,k=(b/s/(n-1)*s+b%s)*8; 25 if(k>=M||ss[t][0]==0&&l<n-1||ss[0][k]==0&&ss[1][k]==0&&ss[t][k]==0){ 26 printf("-\n"); 27 continue; 28 } 29 if(ss[t][0]==0){ 30 ll ans=0; 31 for(int i=0;i<n;i++){ 32 if(i==t)continue; 33 ll x; 34 sscanf(ss[i]+k,"%8x",&x); 35 ans^=x; 36 } 37 printf("%08X\n",ans); 38 } 39 else{ 40 ll ans; 41 sscanf(ss[t]+k,"%8x",&ans); 42 printf("%08X\n",ans); 43 } 44 } 45 return 0; 46 }