可怕的两只咕咕东和宇宙射线(C++)

A 咕咕东的奇遇

题目描述
咕咕东是个贪玩的孩子,有一天,他从上古遗迹中得到了一个神奇的圆环。这个圆环由字母表组成首尾相接的环,环上有一个指针,最初指向字母a。咕咕东每次可以顺时针或者逆时针旋转一格。例如,a顺时针旋转到z,逆时针旋转到b。咕咕东手里有一个字符串,但是他太笨了,所以他来请求你的帮助,问最少需要转多少次。
输入格式
输入只有一行,是一个字符串。
输出格式
输出最少要转的次数。
本来有幅图片的,但是呢,图片就不要奢求了
样例输入
zeus

样例输出
18

解:看到这个题我首先想到的是哈希散列表,
我想到了那个环状的容器,然后每个桶的元素放入过程,
不过这里好像不需要?不过说实话,我看了一边哈希表的概念,
就把它写出来了,emmm.
#include<iostream>
#include<string>
#include<cstring>
#include<stdlib.h>
using namespace std;
char str1[10001];
int len1,mu=26;
long long int sum[10001],ans; 
int main(){
 ans=0;
 scanf("%s",&str1);getchar();
 len1=strlen(str1);
 sum[0]=(long long int)(str1[0]-'a');
 if(sum[0]>13) sum[0]=mu-sum[0];
 for(int mi=1;mi<len1;mi++){
  sum[mi]=(long long int)(str1[mi]-str1[mi-1]);
  if(sum[mi]<0) sum[mi]=-sum[mi];
  if(sum[mi]>13) sum[mi]=mu-sum[mi];
 }
 for(int mj=0;mj<len1;mj++){
  ans+=sum[mj];
 }
 cout<<ans<<endl;
 return 0;
} 

B 咕咕东想吃饭
题目描述
咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买aia_iai​个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎。②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买aia_iai​个生煎。
输入格式
输入两行,第一行输入一个正整数n(1<=n<=100000)(1<=n<=100000)(1<=n<=100000),表示考试周的天数。
第二行有n个数,第i个数ai(0<=ai<=10000)a_i(0<=a_i<=10000)ai​(0<=ai​<=10000)表示第i天咕咕东要买的生煎的数量。
输出格式
如果可以满足咕咕东奇怪的要求,输出"YES",如果不能满足,输出“NO”。(输出不带引号)
样例输入1

4
1 2 1 2

样例输出1

YES

样例输入2

3
1 0 1

样例输出2

NO
#include<iostream>
using namespace std;
long long int days;
int a[100001];
int main(){
 int ticket=0;
 cin>>days;
 for(int i=0;i<days;i++){
  cin>>a[i];
 }
 for(int i=0;i<days;i++){//不妨假设只要是2的倍数,全选方案1 
  if((a[i]-ticket)%2==1 && i<days-1){//是否选择方案2 
   ticket=1;
   if( a[i+1] < 1){
    cout<<"NO"<<endl;
    return 0; 
   }
   if(i+1==days-1){//last of the day
    if( a[i+1]%2 == 0 ){
     cout<<"NO"<<endl;
     return 0;
    }
   }
  }
  else{
   ticket=0;
  }
 } 
 cout<<"YES"<<endl;
 return 0;
}

可怕的宇宙射线(下面的文字还是我截图QQ识别的呢)

题目描述
众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,人外有苟。在浩瀚的宇宙中,存在着一种叫做苟狗的生物,这种生物天
生就能达到人类研究生的知识水平,并且天生擅长CSP,甚至有全国第- -的水平! 但最可怕的是,它可以发出宇宙射线!宇宙射线可以摧毁
人的智商,进行降智打击!
宇宙射线会在无限的维平面上传播(可以看做一个二维网格图), 初始方向默认向上。 宇宙射线会在发射出一-段距离后分裂,向该方向的
左右45°方向分裂出两条宇宙射线,同时威力不变!宇宙射线会分裂n次,每次分裂后会在分裂方向前进a个单位长度。
现在瑞神要带着他的小弟们挑战苟狗,但是瑞神不想让自己的智商降到普通本科生zjm那么菜的水平,所以瑞神来请求你帮他计算出共有多
少个位置会被"降智打击"
输入第- -行包含-一个正整数n(n <= 30),表示宇宙射线会分裂n次
第二行包含n个正整数1.2…an.第个数a(an <= 5)表示第次分裂的宇宙射线会在它原方向上继续走多少个单位长度。
输出描述
输出一个数ans,表示有多少个位置会被降智打击
样例输入
4
4 2 2 3
样例输出
39

解:这道题主要运用了DFS方法,但是如果单纯地从指数
级别的方向思考,肯定会超时的,于是判断条件,因为每条线最长为5
最多有30条线,所以x正方向延伸150.同理可得,负方向延伸150,
y正方向延伸150,负方向延伸150,所以总共最多300*300=90000个点
于是呢,DFS就可以优化了

然后又去看了一波DFS,这个模板太美妙了,借鉴过来了
伪代码DFS出处

void dfs(答案,搜索层数,其他参数){    
    if(层数==maxdeep){        
        更新答案;        
        return;     
    }   
     (剪枝)     
     for(枚举下一层可能的状态){       
          更新全局变量表示状态的变量;        
          dfs(答案+新状态增加的价值,层数+1,其他参数);        
          还原全局变量表示状态的变量;    
      }
}
#include<iostream>
#include<string.h>
using namespace std;
int n,number,index1,index2;//层数 
int a[31];//长度 
int vis[301][301];//访问 
int dx[8]={0,1,1,1,0,-1,-1,-1};//方向 
int dy[8]={1,1,0,-1,-1,-1,0,1};
//坐标,层数,方向,长度 
//最多有30层 ,每层最长为5
//所以x最大为150,y最大也为150,反之为负方向,所以dfs最多300*300个点
int boom[301][301][31][9];//状态 
void dfs(int x,int y,int k,int way){//8个方向 
 if(k==n) return;
 if(boom[x][y][k][way]==0){//状态没有被改变过 
  boom[x][y][k][way]=1;
  for(int i=1;i<=a[k];i++){
   index1=x+dx[way]*i;
   index2=y+dy[way]*i;
   if(vis[index1][index2]==0){//如果没有访问过 
    vis[index1][index2]=1;
    number++;
   }
  }
  int tx=x+dx[way]*a[k];
  int ty=y+dy[way]*a[k];
  int tway=(way+1)%8;
  dfs(tx,ty,k+1,tway);
  tway=(way+7)%8;
  dfs(tx,ty,k+1,tway);
 } 
}
int main(){
 memset(vis,0,sizeof(vis));
 memset(boom,0,sizeof(boom));
 cin>>n;
 for(int i=0;i<n;i++)
  cin>>a[i];
 number=0;
 dfs(150,150,0,0);
 cout<<number<<endl;
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值