zoukankan      html  css  js  c++  java
  • 今天,你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的题解)

  • 相关阅读:
    按需取余
    P3372 【模板】线段树 1
    POJ 3180 The Cow Prom ( korasaju 算法模板)
    【题解】Qin Shi Huang's National Road System HDU 4081 ⭐⭐⭐⭐ 【次小生成树】
    iOS 端容器之 WKWebView 那些事
    无影,会是接近未来的工作场景吗?
    Serverless Devs 2.0 全新发布,让 Serverless 应用开发更简单
    李飞飞:新技术变革时代的数据库产业
    如何攻破容器持久化存储挑战?
    Dubbo 和 HSF 在阿里巴巴的实践:携手走向下一代云原生微服务
  • 原文地址:https://www.cnblogs.com/riced/p/13398196.html
Copyright © 2011-2022 走看看