码迷,mamicode.com
首页 > 其他好文 > 详细

ccf 201903-3 损坏的RAID5

时间:2019-08-05 09:12:12      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:标准输入   数据   数据量   stream   type   bsp   color   splay   偏移量   

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)是块所在硬盘相对校验盘的偏移量。

 

一开始我输入语句是这样写的:

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 }
View Code

 

但是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=n-1+b/s/(n-1)*(n-1)+b/s%(n-1)+1,k=(b/s/(n-1)*s+b%s)*8;t%=n;
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 }

 

ccf 201903-3 损坏的RAID5

标签:标准输入   数据   数据量   stream   type   bsp   color   splay   偏移量   

原文地址:https://www.cnblogs.com/zbhfz/p/11301018.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!