今天,你ak了吗?①

大家好,欢迎来到今天你ak了吗系列,我是解说员,***。

先上题


第一题很简单,让我们来康康。
他说,输入x和y,这是两地的位置,输入a和b,这是缆车的位置。要坐缆车从一地到另一地,求最短路。将靠的近的地方和缆车的距离算一下,再讲得到的距离加一下,就ok了!
代码:

#include<bits/stdc++.h>
using namespace std;
int a[3],b[3];
int main()
{
	scanf("%d%d%d%d",&a[1],&a[2],&b[1],&b[2]);
	sort(a+1,a+3);
	sort(b+1,b+3);
	cout<<abs(a[1]-b[1])+abs(a[2]-b[2])<<endl;
	return 0;
}

然后就欢乐地

为什么会wa掉5个点呢?我们要考虑一下这个问题。如果两个缆车到离它最近的地点综合比两点之间距离还要长咋办?如下:
输入:

86 84 15 78

你跑老远8m再坐缆车过去,下车后再跑69m莫不是*****了?还不如直接走路2m更划算,所以再加一个min函数就ok。代码:

using namespace std;
#include<bits/stdc++.h>
int a[3],b[3];
int main()
{
	scanf("%d%d%d%d",&a[1],&a[2],&b[1],&b[2]);
	sort(a+1,a+3);
	sort(b+1,b+3);
	cout<<min(abs(a[1]-b[1])+abs(a[2]-b[2]),abs(a[1]-a[2]))<<endl;
	return 0;
}

第二题稍微有亿点点难度,它的优化有一些复杂。先上代码:

#include<bits/stdc++.h>
using namespace std;
long long int a,b,c,d,ans;
long long int aa[1001];
int main()
{
	scanf("%lld",&a);
	while(a!=0)
	{
		memset(aa,0,sizeof(aa));c=1;
		while(a!=0)
		{
			aa[a%10]++;
			a/=10;c*=10;
		}
		if(aa[1]==0&&aa[4]==0&&aa[5]==0&&aa[6]==0&&aa[9]==0&&aa[0]==0)
		{
			scanf("%lld",&a);
			continue;
		}
		for(long long int i=0;i*i<=c;++i)
		{
			long long int x=i*i,bb[10]={0,0,0,0,0,0,0,0,0,0};bool flag=false;
			if(x%10==2||x%10==3||x%10==7||x%10==8) continue;
			if(i==0)
			{
				if(aa[0]!=0) printf("0 * 0 = 0\n");
				continue;
			}
			while(x!=0)
			{
				bb[x%10]++;
				if(bb[x%10]>aa[x%10])
				{
					flag=true;
					break;
				}
				x/=10;
			}
			x=i;
			for(int j=0;j<=9;++j) bb[j]=0;
			if(flag==true) continue;
			while(x!=0)
			{
				bb[x%10]++;
				if(bb[x%10]>aa[x%10])
				{
					flag=true;
					break;
				}
				x/=10;
			}
			if(flag==true) continue;
			printf("%lld * %lld = %lld\n",i,i,i*i);
		}
		scanf("%lld",&a);
	}
	return 0;
}

首先.
其中,这里有一个很女少的优化,只有大佬才会
看这里

if(aa[1]==0&&aa[4]==0&&aa[5]==0&&aa[6]==0&&aa[9]==0&&aa[0]==0)
		{
			scanf("%lld",&a);
			continue;
		}

这是干什么用的呢?我们看一组数据就懂了。


一位数 它的平方 平方后的个位
0 0 0
1 1 1
2 4 4
3 9 9
4 16 6
5 25 5
6 36 6
7 49 9
8 64 4
9 81 1

我们可以发现这里每个数的平方位数无非只有1、4、5、6、9、0.当那一组数中不含有这几个数,可以直接continue了。这不是很容易看出来吗!
没事别乱说好不好
这个循环的条件非常玄学:

i*i<=c

为什么是这样的呢?因为这个时候i的位数已经多于n了。


判断部分:

			while(x!=0)
			{
				bb[x%10]++;
				if(bb[x%10]>aa[x%10])
				{
					flag=true;
					break;
				}
				x/=10;
			}
			x=i;
			for(int j=0;j<=9;++j) bb[j]=0;
			if(flag==true) continue;
			while(x!=0)
			{
				bb[x%10]++;
				if(bb[x%10]>aa[x%10])
				{
					flag=true;
					break;
				}
				x/=10;
			}
			if(flag==true) continue;
			printf("%lld * %lld = %lld\n",i,i,i*i);
		}

解释变量:bb[i]:表示i在x(枚举到的数的平方)中出现了bb[i]次

  • aa[i]表示i在a(题目给的数据)中出现了aa[i]次
    变量解释完是不是就一目了然了
    哪有!看不懂!
    就你看不懂~~
    好吧,既然看不懂,那我就解释一下
    第一个while查平方后de枚举数,第二个while查i是否合法。你仔细看,对比下:


你品,你细品~~
被圈起来的地方(就是while里面的内容)是不是完全一样?不一样的在被黄色荧光笔涂上的赋值的语句。
好了,这道题就算讲解完毕,下一道题!!!

未完待续

还没有学会的戳这(某dalao的题解)

posted @ 2020-07-29 17:01  riced  阅读(231)  评论(0编辑  收藏  举报