csp 201903-3

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct DiskData
{
    unsigned char * data;
    void analyseStr(string str)
    {
        data=new unsigned char[str.length()/2];
        for(unsigned i=0; i<str.length()/2; i++)
        {
            data[i]=chartoint(str[i*2])*16+chartoint(str[i*2+1]);
        }
    }
    int chartoint(char d){
        if(d>='a'&&d<='f')return d-'a'+10;
        if(d>='A'&&d<='F')return d-'A'+10;
        return d-'0';
    }
};
struct Disks
{
    int n,s,l,dataLength;//盘数,条带块数,现存盘数
    DiskData *diskDatas;
    int blockCount,*blockNo;
    void getData();
    void fillData(int disk)
    {
        diskDatas[disk].data=new unsigned char[dataLength];
        for(int i=0; i<dataLength; i++)
        {
            diskDatas[disk].data[i]=0;
            for(int j=0; j<n; j++)
            {
                if(j!=disk)
                    diskDatas[disk].data[i]^=diskDatas[j].data[i];
            }
        }
    }
    void print(int disk,int blk)
    {
        printf("%02X%02X%02X%02X\n",diskDatas[disk].data[blk*4],
                diskDatas[disk].data[blk*4+1],
                diskDatas[disk].data[blk*4+2],
                diskDatas[disk].data[blk*4+3]);
    }
    bool check(int disk,int blk){
        if(blk*4+4-1>dataLength)//超出范围
            return false;
        if(n-l>1&&diskDatas[disk].data==NULL)
            return false;//无法推算
        if(diskDatas[disk].data==NULL)fillData(disk);
        return true;
    }
    void getBolck(int r)
    {
        int level=r/((n-1)*s);				//获取读取的数据层数;
        int curp=(n-level%n)-1;			//获取读取的数据层数P块所在盘号,逐次左移一块盘
        int blk=level*s+r%s;				//获取数据所在硬盘的块索引
        int disk=r%((n-1)*s)/s+curp+1;		//获取读取的数据所在硬盘索引,以curp为基准向右走
        disk=disk%n;
        if(check(disk,blk))print(disk,blk);
        else printf("-\n");
    }
    void output()
    {
        for(int i=0; i<blockCount; i++)
            getBolck(blockNo[i]);
    }
};
void Disks::getData()
{
    ios::sync_with_stdio(false);
    cin>>n>>s>>l;
    int no;
    string data;
    dataLength=-1;

    diskDatas=new DiskData[n];
    for(int i=0; i<n; i++)
        diskDatas[i].data=NULL;

    for(int i=0; i<l; i++)
    {
        cin>>no>>data;
        if(dataLength==-1)dataLength=data.length()/2;
        diskDatas[no].analyseStr(data);
    }
    cin>>blockCount;
    blockNo=new int[blockCount];
    for(int i=0; i<blockCount; i++)cin>>blockNo[i];
}
int main()
{
    //freopen("d:\\csp\\201903-3-2.txt","r",stdin);
    Disks ds;
    ds.getData();
    ds.output();
    return 0;
}

以上代码能够通过,但运算时间九百多毫秒,时间消耗主要存在于将接收的字符串分解为字节数组上,尝试调整了一下代码,测试效率200毫秒左右

#include <bits/stdc++.h>
using namespace std;
struct Disks
{
    int n,s,l,dataLength;//盘数,条带块数,现存盘数
    string *diskDatas;
    int blockCount,*blockNo;
    void getData();
    int h2d(char h){
        return h>='0'&&h<='9'?h-'0':h-'A'+10;
    }
    char d2h(int d){
        return d<=9?d+'0':d+'A'-10;
    }
    void getBolck(int r)
    {
        int level=r/((n-1)*s);				//获取读取的数据层数;
        int curp=(n-level%n)-1;			//获取读取的数据层数P块所在盘号,逐次左移一块盘
        int blk=level*s+r%s;				//获取数据所在硬盘的块索引
        int disk=curp+1+r/s%(n-1);		//获取读取的数据所在硬盘索引,以curp为基准向右走
        disk%=n;
        string s="-";
        if(blk*8+8<=dataLength){
            if(!diskDatas[disk].empty()){
                s=diskDatas[disk].substr(blk*8,8);
            }
            else if(n-l==1){
                s="00000000";
                for(int i=0;i<n;i++){
                    if(disk==i)continue;
                    for(int j=0;j<8;j++){
                        s[j]=d2h(h2d(s[j])^h2d(diskDatas[i][blk*8+j]));
                    }
                }
            }
        }
        cout<<s<<endl;
    }
    void output()
    {
        for(int i=0; i<blockCount; i++){
            getBolck(blockNo[i]);
        }
    }
};
void Disks::getData()
{
    ios::sync_with_stdio(false);
    cin>>n>>s>>l;
    int no;
    string data;
    diskDatas=new string[n];
    for(int i=0; i<l; i++)
    {
        cin>>no;
        cin>>diskDatas[no];
    }
    dataLength=diskDatas[no].length();
    cin>>blockCount;
    blockNo=new int[blockCount];
    for(int i=0; i<blockCount; i++)cin>>blockNo[i];
}
int main()
{
    //freopen("d:\\csp\\201903-3-1.txt","r",stdin);
    Disks ds;
    ds.getData();
    ds.output();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值