【ccf-csp题解】第30次csp认证-第三题-解压缩-字符串模拟

原题链接

第30次csp认证第三题原题

题目太长了!这里就只放链接了

这道题目只要仔细阅读,把握好每一个细节,一步一步地做,实际是不难的,这也是csp第三题的特点:题目长、复杂,但是一般不涉及高级算法,难点在于能不能把每一个细节模拟出来。

对于c++,字符串有关的技巧和函数有超级多,比如char *的atoi,itoa,strcmp,strcat,strcpy。string的find和substr,stringstream的字符串分割方法。对于二进制还有很多位运算相关的技巧,对于十六进制-二进制-十进制三者的数字-字符串转换都是在csp第三题经常遇到的。这里就不做过多总结了,以后有时间的话,会专门出一期所有有关上述的总结!

下面是博主写的第三题题解,说实话,代码确实写的不太好,太冗余,大家有兴趣可以参考一下。

满分代码

#include<iostream>
#include<string>
#include<cctype>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
int s,h; 
string has_print;//作用1:回溯 作用2:换行 
int trans(char a,char b)//把二位十六进制数字符变成值 
{
	int num_a,num_b;
	if(islower(a))num_a=a-'a'+10;
	else num_a=a-'0';
	if(islower(b))num_b=b-'a'+10;
	else num_b=b-'0';
	return num_a*16+num_b;
}
int main()
{
	scanf("%d",&s);
	if(s%8==0)h=s/8;
	else h=s/8+1;
	string str;
	bool flag=false;//表示目前还是导引区 
	while(h--)
	{
		string temp;
		cin>>temp;
		str+=temp;
	}
	for(int i=0;i<str.length();i+=2)
	{
		int temp=trans(str[i],str[i+1]);
		if(!flag)
		{
			if(temp>>7&1)continue;
			else
			{
				flag=true;continue;
			}
		}
		else
		{
			if(((temp&1)==0)&&((temp>>1&1)==0)) 
			{
				temp>>=2;
				if(temp<=59)
				{
					int l=temp+1;
					l*=2;
					i+=2;
					while(l--)
					{	
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<str[i];
						has_print+=str[i];
						i++;
					}
					i-=2;
				}
				else
				{
					temp-=59;
					int cnt=0;
					vector<int>len_num;
					while(temp--)
					{
						i+=2;
						len_num.push_back(trans(str[i],str[i+1]));
					}
					for(int j=len_num.size()-1;j>=0;j--)cnt=cnt*256+len_num[j];
					cnt*=2;
					cnt+=2;
					i+=2;
					while(cnt--)
					{
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<str[i];
						has_print+=str[i];
						i++;
					}
					i-=2;
				}
			}
			else if(((temp&1)==1)&&((temp>>1&1)==0))
			{
				temp>>=2;
				int temp1=(temp>>3);
				int o1=temp1;
				temp1<<=3;
				int l=temp-temp1;
				l+=4;
				i+=2;
				int o2=trans(str[i],str[i+1]);
				int o=(o1<<8)+o2;
				l*=2;
				o*=2;
				int index=has_print.length()-o;
				if(o>=l)
				{
					for(int j=index;j<index+l;j++)
					{
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<has_print[j];
						has_print+=has_print[j];
					}
				}
				else 
				{
					int d=l/o,r=l%o;
					while(d--)
					{
						for(int j=index;j<index+o;j++)
						{
							if(has_print.length()>0&&has_print.length()%16==0)
							cout<<endl;
							cout<<has_print[j];
							has_print+=has_print[j];
						}
					}
					for(int j=index;j<index+r;j++)
					{
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<has_print[j];
						has_print+=has_print[j];
					}
				}
			}
			else if(((temp&1)==0)&&((temp>>1&1)==1)) 
			{
				
				temp>>=2;
				int l=temp+1;
				i+=2;
				int b=trans(str[i],str[i+1]);
				i+=2;
				int a=trans(str[i],str[i+1]);
				int o=a*256+b;
				l*=2;
				o*=2;
				int index=has_print.length()-o;
				if(o>=l)
				{
					for(int j=index;j<index+l;j++)
					{
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<has_print[j];
						has_print+=has_print[j];
					}
				}
				else
				{
					int d=l/o,r=l%o;
					while(d--)
					{
						for(int j=index;j<index+o;j++)
						{
							if(has_print.length()>0&&has_print.length()%16==0)
							cout<<endl;
							cout<<has_print[j];
							has_print+=has_print[j];
						}
					}
					for(int j=index;j<index+r;j++)
					{
						if(has_print.length()>0&&has_print.length()%16==0)
						cout<<endl;
						cout<<has_print[j];
						has_print+=has_print[j];
					}
				}
			}
		}
	}
	return 0;
}

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CSP-S2提高组是中国计算机学会(CCF)主办的一项全国性计算机竞赛,旨在挑选出优秀的高中生并为他们提供提高计算机科学和编程能力的平台。2021年第二轮题解分为以下几个部分。 第一是关于石头游戏的思考。目给出了一堆石头的数量,两位玩家轮流选择石头进行取走,每可以取走1个或者2个石头,最后无法继续取走者输掉游戏。通过观察可以发现,如果一开始给定的石头数量是3的倍数,那么第一个选手必胜;否则,第一个选手无法必胜。这是因为无论第一个选手怎么选取,第二个选手总可以使得每一轮选取后的石头数量保持在3的倍数。因此,只需要判断起始时石头数量是否为3的倍数即可。 第二是关于好书的购买。目给出了若干种书的价格和折扣情况,要求在有限的预算下买到尽可能多的书籍。这是一个经典的背包问。使用动态规划算法可以解决,按照价格从小到大的顺序遍历书籍,设置一个二维数组dp[i][j]表示在前i本书中,花费j的预算能够买到的最多书籍数量。状态转移方程为:dp[i][j]=max(dp[i-1][j], dp[i-1][j-price[i]]+1)。最终的结果即为dp[n][budget],其中n为书籍总数,budget为预算。 第三是关于均匀生成所有正整数的问目给出了一个区间[L, R],要求输出在该区间内存在的所有正整数。首先通过观察可以发现,对于任意的正整数x,若2x在区间[L, R]内,那么x也在该区间内;若2x+1在区间[L, R]内,那么x也在该区间内。基于这个思路,可以使用递归的方式实现。若L<=R,则输出L,然后递归输出从2*L到R的所有整数。若L>R,则结束递归。 以上就是CSP-S2提高组2021第二轮题解的简要概述。希望这些解思路对参与竞赛的同学有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值