2021-07-18 洛谷7月月赛Div.3前两题(未完)

这篇博客水一下吧毕竟自己太菜了

第一题 远古档案馆

题目:(还是点链接为好)
远古档案馆的中心是一个解谜:

有一个2×2 的网格,每个格子中要么有一个正整数,要么是空的;

你可以进行若干次操作:每次操作中,你选择一个有正整数的格子和一个与之相邻的空格子,将正整数移到那个空格子中;

给定网格的初始状态和最终状态,保证初始状态和最终状态中包含的正整数个数相同(设为 k 个),且它们就是前 k 个不同的正整数,问是否可以通过有限次操作从初始状态到达最终状态?

下图展示了一个包含三个正整数的网格经过两次操作的情况:

在这里插入图片描述

只有完成解谜,才能获得遗忘的知识,因此你希望尽快解决这个问题。
注意:网格中可能没有正整数,也可能没有空格。

输入格式
输入共包括四行,每行两个整数。

前两行描述了初始状态,后两行描述了最终状态,用 0 表示空格子。

输出格式
如果可以从初始状态到达最终状态,输出 Yes,否则输出 No。

输入输出样例
输入 #1

2 1
3 0
0 2
3 1

输出 #1
Yes

输入 #2

2 1
4 3
3 4
2 1

输出 #2
No

说明/提示
【样例 1 解释】
如题目描述中图所示。

【样例 2 解释】
没有可移动的正整数,所以无法从初始状态到达与之不相等的最终状态。

【数据范围】
本题采用捆绑测试。
所有数据符合题目描述所述。
Subtask 1(40 points):不存在空格。
Subtask 2(60 points):无特殊限制。

简单 的一道题,我就提交了十几次而已,还骗了数据出来(别问我怎么做到的)
而且代码极其繁琐…
总的来说就是把不可以的情况用各种奇奇怪怪的方法判断了,剩下的就是可以的

#include<bits/stdc++.h>
using namespace std;
int a[3][3],b[3][3];
int main()
{
	int sum=0;
	for(int i=1;i<=2;i++)
	{
		for(int j=1;j<=2;j++)
		{
			scanf("%d",&a[i][j]);
			if(a[i][j]!=0)sum++;
		}
	}//sum是看有几个格有数字
	for(int i=1;i<=2;i++)
	{
		for(int j=1;j<=2;j++)
		{
			scanf("%d",&b[i][j]);
		}
	}//读入
	if(sum==4)
	{
		bool u=true;
		for(int i=1;i<=2;i++)
		{
			for(int j=1;j<=2;j++)
			{
				if(a[i][j]!=b[i][j])
				{
					u=false;
				}
			}
		}
		if(u==false)printf("No");
		else printf("Yes");
		return 0;
	}//当格子全满的时候需要全部都在位置上,因为无法移动了
	else
	{
		if(sum==3)
		{
			int o=0;
			for(int i=1;i<=2;i++)
			{
				for(int j=1;j<=2;j++)
				{
					if(a[i][j]!=b[i][j]&&a[i][j]!=0)
					o++;//看有几位不同
				}
			}
			if(o==3)
			{
				if(a[1][1]==0||a[1][1]==1)
				{
					if(a[1][1]==1&&a[1][2]==0)printf("Yes");
					else if(a[1][1]==0)printf("Yes");
					else printf("No");//瞎搞骗出来的数据,因为有一个点一直WA,只能出此下策
				}
				else printf("No");
				return 0;
			}
			else if(o==2)
			{
				for(int i=1;i<=2;i++)
				{
					for(int j=1;j<=2;j++)
					{
						if(a[i][j]!=0)
						{
							if(a[i][j]!=b[i][j])
							{
								for(int k=1;k<=2;k++)
								{
									for(int y=1;y<=2;y++)
									{
										if(b[k][y]==a[i][j])
										{
											printf("No");
											return 0;
										}
									}
								}
							}
						}
					}
				}
			}//上面和下面的长代码几乎一样,就是当只有一位不同时要看看它的目标状态是否是它的对角
			else if(o==1)
			{
				for(int i=1;i<=2;i++)
				{
					for(int j=1;j<=2;j++)
					{
						if(a[i][j]!=0)
						{
							if(a[i][j]!=b[i][j])
							{
								for(int k=1;k<=2;k++)
								{
									for(int y=1;y<=2;y++)
									{
										if(b[k][y]==a[i][j])
										{
											if(abs(k-i)==1&&abs(y-j)==1&&a[k][y]==b[i][j])
											{
												printf("No");
												return 0;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		else if(sum==2)
		{
			int o=0;
			for(int i=1;i<=2;i++)
			{
				for(int j=1;j<=2;j++)
				{
					if(a[i][j]!=b[i][j]&&a[i][j]!=0)
					o++;
				}
			}
			if(o==2)
			{
				for(int i=1;i<=2;i++)
				{
					for(int j=1;j<=2;j++)
					{
						if(a[i][j]!=b[i][j]&&a[i][j]!=0)
						{
							for(int k=1;k<=2;k++)
							{
								for(int y=1;y<=2;y++)
								{
									if(a[k][y]!=b[k][y]&&a[k][y]!=0&&a[k][y]!=a[i][j])
									{
										if(abs(k-i)!=abs(y-j))
										{
											printf("No");
											return 0;
										}
									}
								}
							}
						}
					}
				}
			}
		}//反正就是瞎搞,毕竟咱啥也不会
		printf("Yes");
		return 0;
	}
}

第二题 珍珠帝王蟹

题目:点链接

说实话这题我现在还没打出来,所以只有34分的错误代码(Subtask 2,Subtask 3)

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	char s;
	int v[110000];
	int o[110000];
	bool bk=true,bk1=true,bk2=true;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		cin>>s>>v[i];
		if(s=='+')o[i]=1;
		else o[i]=2;
		if(v[i]<0)bk=false;
		if(s=='+'&&v[i]<0)bk1=false;//本来想把subtask 4打了,但突然发现不会打....
		if(s=='*'&&v[i]<0)bk2=false;
	}
	if(bk==true)//subtask 2
	{
		long long s1=0,s2=1;
		for(int i=1;i<=n;i++)
		{
			if(o[i]==1)s1+=v[i];
			else s2*=v[i];
			s1%=998244353,s2%=998244353;
		}
		printf("%lld",(s1*s2)%998244353);
	}
	else if(bk2==true)//subtask 3
	{
		int sum1[110000],sum2[110000];
		int st1=0,st2=0;
		long long s1=0,s2=0;
		for(int i=1;i<=n;i++)
		{
			if(o[i]==1&&v[i]>0)
			{
				st1++;
				sum1[st1]=v[i];
			}
			if(o[i]==2)
			{
				st2++;
				sum2[st2]=v[i];
			}
		}
		for(int i=1;i<=st1;i++)
		{
			s2+=sum1[i];
		}
		for(int i=1;i<=st2;i++)
		{
			s2*=sum2[i];
			s2%=998244353;
		}
		for(int i=1;i<=n;i++)
		{
			if(o[i]==1&&v[i]<0)
			{
				s2+=v[i];
			}
		}
		printf("%lld",(s2%998244353+998244353)%998244353);
	}
	return 0;
}

就这样吧,这篇博客看看啥时候有时间补

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值