week4 csp模拟

标题

一:
(1)问题描述:

输入一个字符串输出最小的转动次数。
(2)思路:
因为是个圆形所以我想到了对称的原理,在整个圆形中离当前字母最远的点就是当前字母所对称的点,所以判断上一个字母是在当前字母对应字母的哪边就可以了,我是将上一个字母减去当前字母得到一个int值去这个值的绝对值然后用26减去它,在比较这两个值的大小进行判断。

#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) 
{
	string a="";
	cin>>a;
	long long b,c,result=0;
	c=a.length();
	for(int i=0;i<c;i++)
	{
		if(i==0)
		{
			int a1='a'-a[0];//最开始的时候a在最上面用a减去
			if(a1<0)
			{
				a1=-a1;
			}
			int a2=26-a1;
			if(a2>a1)
			{
				result=result+a1;
			}
	        else
	        {
	        	result=result+a2;
			}
		}
		else
		{
			int a1=a[i-1]-a[i];//上一个字母减去本轮字母
			if(a1<0)
			{
				a1=-a1;
			}
			int a2=26-a1;
			if(a2>a1)
			{
				result=result+a1;
			}
	        else
	        {
	        	result=result+a2;
			}
		}
		
	}
    cout<<result;
   	return 0;
}

二:
(1):问题描述

(2)思路:
这道题的思路就是能不买一个的就不买一个的从第一个开始判断是否需要买一个的(%2),如果需要就继承一个1到下一个,对下一个减去1继续进行判断(若减一之前为0则证明不可行,或者到最后一天的时候减去1为奇数也不行,这是两个终止条件)。

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv)
{
	long long n;
	int a[100005];//存储数据
	cin>>n;
	bool result=true;//最后输出的判断条件true为可行,false为不可行
	int ans=0,ans1;//ans存储今天的购买是否会买用券的
	for(long long i=0;i<n;i++)
	{
		cin>>a[i];
		if(i==0)
		{
			ans=a[0]%2;//最开始直接求余(为了尽量避免买用券的情况)
		}else
		{
				if(a[i]==0)
				{
					if(ans==1)
					{
	    			   result=false;	
     				   break;
					}
					else
					{
						result=true;
					}

				}else
				{
					if(i==n-1)
					{
						a[i]=a[i]-ans;
						ans=a[i]%2;
						if(ans==1)
						{
							result=false;
							break;
						}else
						{
							result=true;
							break;
						}
					}
					a[i]=a[i]-ans;
					ans=a[i]%2;
				}
		}
	}
	if(result==true)
	{
		cout<<"YES";
	}else
	{
		cout<<"NO";
	}
	return 0;
}

三:宇宙射线
(1)问题描述

对一条射线逐步进行分裂,每次分裂行走一定的步数
(2)思路;
直接运用bfs并实现剪枝就可实现,因为可以走八个方向每一步的方向不同所以四维数组中前两维存储地址第三维存储走到哪一步,第四维存储该往哪个方向扩展。在进行剪枝的时候若方向相同,位置相同则只压入一次多余的情况抛弃减少运行时间。倒数第二步是最后的要入步骤,在最后一步中只需取出即可,不在压入。

#include<iostream>
#include<queue>
using namespace std;
int n,A1[40],x1,x2,result=0;
bool ans[340][340][40][40];
int dx[] = { 0,1,1,1,0,-1,-1,-1 };
int dy[] = { 1,1,0,-1,-1,-1,0,1 };
struct A
{
	int first, second, n,xz;
};
void bfs()
{
	A k;
	queue<A>q;
	k.first = 170;
	k.second = 170;
	k.n = 1;
	k.xz = 0;
	q.push(k);
	ans[170][170][k.n][k.xz] = true;
	while (!q.empty())
	{
		A now = q.front();
		q.pop();
		x1 = now.first;
		x2 = now.second;
		for (int i = 1; i <= A1[now.n]; i++)
		{
			x1 = x1 + dx[now.xz];
			x2 = x2 + dy[now.xz];
			if (ans[x1][x2][0][0] == false)
			{
				ans[x1][x2][0][0] = true;
				result++;
			}
		}
		if (now.n < n)
		{
			A cc1, cc2;
			cc1.n = now.n + 1;
			cc1.xz = (now.xz + 1) % 8;
			cc1.first = x1;
			cc1.second = x2;
			cc2.n = now.n + 1;
			cc2.xz = (now.xz + 7) % 8;
			cc2.first = x1;
			cc2.second = x2;
			if(ans[cc1.first][cc1.second][cc1.n][cc1.xz]==false)
            {
                ans[cc1.first][cc1.second][cc1.n][cc1.xz]=true;
                q.push(cc1);
            }
            if(ans[cc2.first][cc2.second][cc2.n][cc2.xz]==false)
            {
                ans[cc2.first][cc2.second][cc2.n][cc2.xz]=true;
                q.push(cc2);
            }
		}
	}
	cout<<result;
}
using namespace std;
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> A1[i];
	}
	bfs();
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值