A题
题意:
一个圆环包含26个英文字母,顺时针从a到z排列,有一个指针指向a,每次可以顺时针或逆时针旋转一格。如a顺时针旋转到z,逆时针旋转到b。现在有一个字符串(长度<=10000),请输出要得到这个字符串最少需要旋转的次数。
**思路:**将指针的位置随着字符串的位置移动,判断指针所指与指针下一个字符之间的距离a,顺时针转动的距离等于26-a,做判断
代码:
#include <cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
string s;
cin>>s;
int tot=0;
char now = 'a';
int term = 0;
int term0 = 0;
for(int i=0;i<s.size();i++)
{
if(now == s[i]) continue;
else if(now > s[i]) term = now -s[i];
else if (now < s[i]) term = s[i] - now;
term0 = 26 - term;
if(term >= term0) tot += term0;
else tot += term;
now = s[i];
}
cout<<tot;
return 0;
}
总结:
之前思路有问题,用双向链表来做的,一开始想的是双向链表指针可以向前向后。后面发现,顺时指针到z就截止所以每次都要重新改变链表头指针的位置,可是反向链表的头指针无法改变,需要进一步的改进了解。
B题
题意:
咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买ai个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎。②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买ai个生煎
Input
输入两行,第一行输入一个正整数n(1<=n<=100000),表示考试周的天数。
第二行有n个数,第i个数ai(0<=ai<=10000)表示第i天咕咕东要买的生煎的数量。
Output
如果可以满足咕咕东奇怪的要求,输出"YES",如果不能满足,输出“NO”。(输出不带引号)
题意:
出现NO的情况有两种
(1)今天有卷可以用但是不买生煎直接退出输出NO
(2)最后一天,买完生煎以后还剩一张劵输出NO
开始判断中间的天,到第i天:如果今天有劵可以用,先把劵juan–,ai–.先两个两个的买保证最好不要剩劵,判断(ai % 2 是否等于0)如果不等于0,则juan++,第二天有劵用
代码:
#include <cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
int n;
cin>>n;
int juan=0;
for(int i=0;i<n;i++)
{
int ai;
cin>>ai;
if(juan == 1)//如果有券,先把劵用了
{
if(ai == 0)
{
cout<<"NO";
return 0;
}
else
{
ai--;
juan--;
}
}
if(ai % 2 == 0)
continue;
else if(ai % 2 == 1)
juan++;
}
if( juan == 1)
cout<<"NO";
else
cout<<"YES";
return 0;
}
总结:
这道模拟题的场景要比第一题的难,但是可以变为第i天考虑,考虑第i天的情况,然后对特殊情况进行处理。
C题
题意:
宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的左右45度方向分裂出两条宇宙射线,同时威力不变。宇宙射线会分裂n次(n<=30),每次分裂后会在分裂方向上前进ai个单位长度(ai<=5)。请输出有多少个位置会被宇宙射线影响到。
思路:这道题要用到剪枝才会降低时间复杂度,用到dfs
代码:
#include <iostream>
#include<queue>
using namespace std;
int n;
int s[32];//分裂次数
int road[400][400];//记录是否经过过这个位置
int visit[400][400][32][8];//记录是否分裂过这个方向
int dx[] ={ 1,1,0,-1,-1,-1,0,1};
int dy[] ={0,1,1,1,0,-1,-1,-1};
int tot=0;
struct Node
{
int x;//记录位置
int y;
int sep;//分裂个数
int dire;//分裂方向
};
void dfs(int x,int y,int sep,int dire)
{
//剪枝
if(sep> n) return;
if(visit[x][y][sep][dire]) return;//经历过此分裂方向
visit[x][y][sep][dire] = 1;
for(int i=0;i<s[sep];i++)
{
x += dx[dire];
y += dy[dire];
if(road[x][y] != 1)
{
road[x][y] = 1;
tot++;
}
}
sep++;
dfs(x,y,sep,((dire+1)%8));
dfs(x,y,sep,((dire+7)%8));
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s[i];
}
dfs(200,200,0,0);
cout<<tot<<endl;
}