大家好,欢迎来到今天你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的题解)