csp模拟补题

题目A - 咕咕东的奇遇

咕咕东是个贪玩的孩子,有一天,他从上古遗迹中得到了一个神奇的圆环。这个圆环由字母表组成首尾相接的环,环上有一个指针,最初指向字母a。咕咕东每次可以顺时针或者逆时针旋转一格。例如,a顺时针旋转到z,逆时针旋转到b。咕咕东手里有一个字符串,但是他太笨了,所以他来请求你的帮助,问最少需要转多少次。
————————————————
解题过程
第一次模拟唯一一道提交上去的题。菜到令人发指,前途一片黑暗。
利用ascii码计算距离,就是文字之间的距离如果大于13就逆时针,小于13就顺时针转,有26个字母,逆时针的距离是26-顺时针距离。
虽然很简单但是还在找BUG上浪费许许多多时间,说明很不熟练需要多写代码……

#include <iostream>
#include <string>
#include <cmath>
using namespace std;

int main(int argc, char** argv) {
	string z;
	cin>>z;
	int pos=0;
	int pre=0;
	int sum=0,p=0;
	int n=z.size();
	for(int i=0;i<n;i++)
	{ pos=z[i]-97;
	  p=(abs(pos-pre));
	  if(p>13)
	  p=26-p;	  
	  pre=pos;	
	  sum=sum+p;	
	}
	
	cout<<sum;
	
	return 0;
}

B - 咕咕东想吃饭

咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买ai个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎。②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买ai个生煎。
————————————————
反思
如果脑子不够解不开密码锁又想开门,那就只能暴力。如果太弱那么连暴力的资本都没有。虽然写了暴力方法但是没能交上去,在最后一分钟被网站拒之门外,码力弱的像只猴子。 后来补题的时候发现暴力方法能过3个点,改了改还过了4个。虽然后来想到了可能和奇偶数有关但是还是不ok
解题过程
所有的两个生煎的买法都可以被方案1解决,用方案2是没有意义的,也就是说生煎只有0、1(奇)、2(偶)三种状态,输入的时候把多余的生煎私吞转化为0、1、2 。
因为要确保最后没有券浪费所以从最后一天开始向前看,如果最后一天是2或0则前一天不需要券,如果是1则前一天买了一个券,则前一天要买的生煎数-1,如果出现某一天生煎为负说明没有方法则退出循环,如果到循环结束生煎数全部正常,则可以输出yes。
第一天生煎数不可以是1,因为只有两种情况会是1,第一天偶数第二天奇数(一张券不够两张浪费),第一天奇数以后都是偶数(最后一天浪费券)

#include <iostream>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cmath>
using namespace std;

 int a[100020];
int main(int argc, char** argv) {
    int n,fl=0,f=0,a1=0,ticket=0;
    cin>>n; 
   
    for(int i=0;i<n;i++)
    { scanf("%d",&a1);
      a[i]=a1%2;
	  if(a[i]==0&&a1!=0)
	  a[i]=2;	
	  
	}
    for(int i=n-1;i>0;i--)
    {  
	  if(a[i]<0)
      { f++;
	    break;
	  }
	  if(a[i]%2==0)
      {continue; 	
	  }
      if(a[i]==1)
	  { a[i-1]--; 
	   }		
	}
    
	if(a[0]==1)
	f=1;
    
	if(f==1)
	cout<<"NO";
	else
	cout<<"YES";	
	return 0;
}

C - 可怕的宇宙射线

众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,人外有苟。在浩瀚的宇宙中,存在着一种叫做苟狗的生物,这种生物天生就能达到人类研究生的知识水平,并且天生擅长CSP,甚至有全国第一的水平!但最可怕的是,它可以发出宇宙射线!宇宙射线可以摧毁人的智商,进行降智打击!
宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的左右45°方向分裂出两条宇宙射线,同时威力不变!宇宙射线会分裂n次,每次分裂后会在分裂方向前进ai个单位长度。
现在瑞神要带着他的小弟们挑战苟狗,但是瑞神不想让自己的智商降到普通本科生那么菜的水平,所以瑞神来请求你帮他计算出共有多少个位置会被"降智打击"
————————————————
反思
补题的时候才来的及读题的一道题,知道自己菜所以也没有在模拟时拿分的想法 ,结果就交了一个题。码力严重不足,知识严重不足,智商严重欠费
解题过程
其实每次移动45°的射线只有8种分裂状态(上,上右,右,下右,下,下左,左,上左 )像在之前走迷宫的时候一样 用数组储存8个移动状态方便移动。
用结构体表示位置状态,用一个数组reach记录情况避免重复情况(起点方向次数一致时是重叠的)下图(不是苯环 )红圈圈的地方开始重叠。
用set来记录位置,可以避免记录重叠位置。
每个射线分裂45°(当前分裂状态向右或下偏转)和-45°(向左或上偏)
递归求解。分裂次数达到后输出set的size,就是所有经过的位置和。
红圈重复

#include <iostream>
#include <cstdlib>
#include <set>
using namespace std;
int a[40];
int count=0;
int xc[8]={0,1,1,1,0,-1,-1,-1};//上,上右,右,下右,下,下左,左,上左 
int yc[8]={1,1,0,-1,-1,-1,0,1};
bool reach[700][700][32][8]={0};
int n=0;
struct xy
{int x;
 int y;	
 void sp(int f)
 {
 	x=x+xc[f];
 	y=y+yc[f];
 }
 bool operator<(const xy& p) const 
 { if(x!=p.x)
   {return x<p.x;
   	
	} 
  else
  return y<p.y;
  }
 } ;
set <xy> vis;
void splitter(int ind,int times,xy pos )
{ 
	if(times>n-1)
	return;
	if(reach[pos.x][pos.y][times][ind]==1)
	return;
	else
	{reach[pos.x][pos.y][times][ind]=1;
	 for(int i=0;i<a[times];i++)//前进
	{
		pos.sp(ind);
		vis.insert(pos);
	}
	splitter((ind+7)%8,times+1,pos);//分裂
	splitter((ind+1)%8,times+1,pos);
   }	
}

int main(int argc, char** argv) {
	
	cin>>n;
	for(int i=0;i<n;i++ )
	{
		cin>>a[i]; 
	}
	  xy begin;
	  begin.x=300; begin.y=300;
	splitter(0,0,begin);
	cout<<vis.size();  
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值