设直角三角形的两条直角边长度分别是 和a,b斜边长度是c,那么可以用数学语言表达:a2+b2=c2,这就是勾股定理,但是在本题中, 勾股定理它!变!异!了!,若三个数满足a2+b2=c,那么称该数满足变异的勾股定理, 现在给定一个数c,如果存在两个数a与b满足a2+b2=c,那么输出Yes,否则输出No.
数据范围:
c<=231−1
输入格式:
输入一个整数c
输出格式:
输出Yes或No
输入样例1:
5
输出样例1:
在这里给出相应的输出。例如:
Yes
输入样例2:
2147483647
输出样例2:
在这里给出相应的输出。例如:
No
思路
我的做法是暴力对于c寻找1到√c的数x,判断x,1-x是否可开方,并判断c是否可开方。
后来群里大佬发布解法,此篇博客记录一下大佬解法
关于c++ map与unordered_map区别及使用
大佬代码
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int> h;
int find(int c){
for(int i=0;(long long)i*i<=c;i++) h[i*i]=1;
for(int i=0;(long long)i*i<=c;i++){
if(h[c-i*1]) return 1;// if (h. count(c−i ∗ i ))
}
return 0;
}
int main(){
int c;
cin>>c;
if(find(c)) puts("Yes");
else puts("No");
return 0;
}
我的代码
#include<bits/stdc++.h>
using namespace std;
map<int,int> mp;
int fun(int x){
if(mp[x]==1) return 1;
else if(mp[x]==-1) return 0;
else{
int flag=0;
int a=(int)sqrt(x);
if(a*a==x) flag=1;
else if((a+1)*(a+1)==x) flag=1;
else if((a-1)*(a-1)==x) flag=1;
if(flag){
mp[x]=1;
return 1;
}
else{
mp[x]=-1;
return 0;
}
}
}
int main(){
int c,flag=0;
scanf("%d",&c);
for(int i=1;i<sqrt(c);i++){
if(fun(i)&&fun(c-i)){
flag=1;
}
}
if(flag||fun(c)) printf("Yes");
else printf("No");
return 0;
}