咕咕东的奇遇
题目描述
咕咕东是个贪玩的孩子,有一天,他从上古遗迹中得到了一个神奇的圆环。这个圆环由字母表组成首尾相接的环,环上有一个指针,最初指向字母a。咕咕东每次可以顺时针或者逆时针旋转一格。例如,a顺时针旋转到z,逆时针旋转到b。咕咕东手里有一个字符串,但是他太笨了,所以他来请求你的帮助,问最少需要转多少次。
加个示意图
输入格式
输入只有一行,是一个字符串。
输出格式
输出最少要转的次数。
思路:创建一个双向环形链表类,实现函数count(node* first, char aim)表示从位置first开始向两边转动到aim的最少转动次数。对于字符串第一个字符,first从‘a’开始,接下来对于每一个字符,从上一个位置的字符开始找到aim,统计总共转动的次数即可。
#include <iostream>
#include <string>
using namespace std;
struct node {
char x='1';
node* next = NULL;
node* pre = NULL;
node(){}
};
class zimu {
public:
zimu() {
head = new node();
last = new node();
head->x = 'a';
last->x = 'b';
head->pre = last;
last->next = head;
head->next = last;
last->pre = head;
first = head;
num = 0;
}
void count(node* first, char aim);
void insert(char x);
node* head;
node* last;
node* first;
int num;
};
void zimu::insert(char x) {
node* p;
p = new node();
p->x = x;
this->last->next = p;
p->pre = this->last;
this->last = p;
this->last->next = this->head;
this->head->pre = this->last;
}
void zimu::count(node* first, char aim) {
node* a = first;
node* b = first;
node* q=NULL;
int n = 0;
while (a->x != aim && b->x != aim) {
a = a->next;
b = b->pre;
n++;
}
if (a->x == aim) q = a;
else if (b->x == aim) q = b;
this->num = this->num + n;
this->first = q;
}
int main() {
zimu t;
int i,n=0;
for (i = 2; i <= 25; i++) {
t.insert(t.head->x + i);
}
string s;
cin >> s;
while (n != s.size()) {
t.count(t.first, s[n]);
n++;
}
cout << t.num;
return 0;
}
咕咕东想吃饭
题目描述
咕咕东考试周开始了,考试周一共有n天。他不想考试周这么累,于是打算每天都吃顿好的。他决定每天都吃生煎,咕咕东每天需要买ai个生煎。但是生煎店为了刺激消费,只有两种购买方式:①在某一天一次性买两个生煎。②今天买一个生煎,同时为明天买一个生煎,店家会给一个券,第二天用券来拿。没有其余的购买方式,这两种购买方式可以用无数次,但是咕咕东是个节俭的好孩子,他训练结束就走了,不允许训练结束时手里有券。咕咕东非常有钱,你不需要担心咕咕东没钱,但是咕咕东太笨了,他想问你他能否在考试周每天都能恰好买ai个生煎。
输入格式
输入两行,第一行输入一个正整数n
(1<=n<=100000),表示考试周的天数。
第二行有n个数,第i个数
ai(0<=ai<=10000)表示第i天咕咕东要买的生煎的数量。
输出格式
如果可以满足咕咕东奇怪的要求,输出"YES",如果不能满足,输出“NO”。(输出不带引号)
样例输入1
4
1 2 1 2
样例输出1
YES
样例输入2
3
1 0 1
样例输出2
NO
思路:首先统计他n天总共要买的数量,若为奇数则输出“NO”,因为不管是一次买两个或者买一个送一张券都相当于买了偶数个,所以最后总共买的数量一定是偶数。
若购买总数为偶数,设置一个变量为s表示剩余的券的数量,初始化为0,对于每一天需要购买的数量,与s进行比较,若购买数量小于s,则表示当天买的数量不能满足要求。之后更新s=(day[i]-s)%2;可以设置一个逻辑变量判断是否可以满足要求。
#include <iostream>
using namespace std;
int main(){
int day[200000],i,x,sum=0,s=0;
cin>>x;
for(i=0;i<x;i++){
cin>>day[i];
sum=sum+day[i];
}
bool lo=true;
if(sum%2!=0){
cout<<"NO";
return 0;
}
for(i=0;i<x;i++){
if(day[i]-s<0){
lo=false;
break;
}
s=(day[i]-s)%2;
}
if(lo) cout<<"YES";
else if(!lo) cout<<"NO";
return 0;
}
可怕的宇宙射线
题目描述
众所周知,瑞神已经达到了CS本科生的天花板,但殊不知天外有天,人外有苟。在浩瀚的宇宙中,存在着一种叫做苟狗的生物,这种生物天 生就能达到人类研究生的知识水平,并且天生擅长CSP,甚至有全国第一的水平!但最可怕的是,它可以发出宇宙射线!宇宙射线可以摧毁 人的智商,进行降智打击! 宇宙射线会在无限的二维平面上传播(可以看做一个二维网格图),初始方向默认向上。宇宙射线会在发射出一段距离后分裂,向该方向的 左右45°方向分裂出两条宇宙射线,同时威力不变!宇宙射线会分裂 次,每次分裂后会在分裂方向前进 个单位长度。 现在瑞神要带着他的小弟们挑战苟狗,但是瑞神不想让自己的智商降到普通本科生 那么菜的水平,所以瑞神来请求你帮他计算出共有多 少个位置会被"降智打击"
输入描述
输入第一行包含一个正整数 ,表示宇宙射线会分裂 次 第二行包含n个正整数 ,第 个数 表示第 次分裂的宇宙射线会在它原方向上继续走多少个单位长度。
输出描述
输出一个数 ,表示有多少个位置会被降智打击
思路:创建两个数组x_way[] = { 0,1,1,1,0,-1,-1,-1 };
y_way[] = { 1,1,0,-1,-1,-1,0,1 }表示对于每一个点可以移动的八个位置。对于每一个顶点,它的分裂遵循以下规律:
每个顶点的分裂方向为当前方向way:(way + 7) % 8和 (way + 1) % 8;
再创建一个数组判断此点是否经过过,采用广度优先搜索方法,此题解决。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <set>
using namespace std;
struct node {
int x;
int y;
int way;
bool operator<(const node& s) const
{
if (x != s.x) return x < s.x;
else if (y != s.y) return y < s.y;
else if (way != s.way) return way < s.way;
else return false;
}
};
int x_way[] = { 0,1,1,1,0,-1,-1,-1 };
int y_way[] = { 1,1,0,-1,-1,-1,0,1 };
set<node> v1, v2;
int gg[800][800] = { 0 };
int main() {
int n, num = 1;
cin >> n;
int a[100] = { 0 };
for (int i = 0; i < n; i++) {
cin >> a[i];
}
node first;
first.x = 300;
first.y = 300;
first.way = 0;
gg[first.x][first.y] = 1;
v1.insert(first);
for (int i = 0; i < n; i++) {
for (auto it = v1.begin(); it != v1.end(); it++) {
node ll, r;
int x = it->x, y = it->y, way = it->way;
for (int l = 0; l < a[i] - 1; l++) {
x = x + x_way[way];
y = y + y_way[way];
if (gg[x][y] == 0) {
gg[x][y] = 1;
num++;
}
}
if (i == n - 1) continue;
ll.way = (way + 7) % 8;
r.way = (way + 1) % 8;
ll.x = x + x_way[ll.way];
ll.y = y + y_way[ll.way];
r.x = x + x_way[r.way];
r.y = y + y_way[r.way];
if (gg[ll.x][ll.y] == 0) {
gg[ll.x][ll.y] = 1;
num++;
}
if (gg[r.x][r.y] == 0) {
gg[r.x][r.y] = 1;
num++;
}
v2.insert(ll);
v2.insert(r);
}
v1 = v2;
v2.clear();
}
cout <<num;
return 0;
}