#include<iostream>
using namespace std;
const int N=1010;
int x[N],y[N];
int k1,k2,p1,p2;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>x[i];
for(int i=0;i<n;i++) cin>>y[i];
int cnt;
int res=0;
for(int i=0;i<n;i++){
k1=y[i]-x[i];
for(int j=0;j<n;j++){
k2=y[j]+x[j];
cnt=0;
for(int k=0;k<n;k++){
p1=y[k]-x[k];
p2=y[k]+x[k];
if(p1==k1||p2==k2) cnt++;
}
res=max(res,cnt);
}
}
cout<<res<<endl;
return 0;
}
ax+by=c
三层循环,最外面两层是每个斜率为1和-1的时候(x,y)所在直线的“c”值.
而题目要找哪两条直线上所在点最多,那么也就是说如果你先确定任意(x,y)所在直线,在去找其他点是否在该直线上即可,也就是上面所说的“c”值。
外面两层循环分别敲定一条直线,最里面的循环则去确定外面的"c"值是否和最里层的相等
为什么说相等呢?因为ax+by=c;要确定一条直线是否和另一条重合,就要证明a,b,c都一样,斜率确定为1和-1,那么就确定了a,b;只需要确定c是否相等即可。
第三层循环就是遍历每一个点,判断是否重合,重合就+1,用cnt计数;而第三层循环每一次结束,就要与上一次的比较,得到最大值,所以要把每一次的值存到res里。
#include<iostream>
#include<cstring>
using namespace std;
/*若pre[3]=7;那么视为3的上级是7 下标不可重复,值可重复,
对应一个父节点可以对应多个子节点 */
const int N=100010;
int n,m;
int p[N];
int find(int x){
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
int main(){
cin>>n>>m;
for(int i=0;i<=n;i++) p[i]=i;
int a,b,res=n-1;
int fa1,fa2;
for(int i=1;i<=m;i++){
cin>>a>>b;
fa1=find(a);
fa2=find(b);
if(fa1!=fa2) p[fa1]=fa2,res--;
}
cout<<res<<endl;
return 0;
}
find()函数是用来找该数是节点,如果是则继续找该数的上级,直到找到该数的最高节点;
先保证n个数要n-1条线,就是最简单的一个一个排排连;然后再这个基础上减去题目要给的连线;
为什么不计算题目给了多少线然后减去?因为不能保证题目每次会给不同的点
每一次接收到题目给的点,就去查那两个点是否有节点,即 是否被连线了(没有连线则表示要给这个点一条线连接,如果连了,不管有几个父节点,都不用在给线去连接)
然后是去判断两个数的最高节点是不是同一个,如果不相等,则表示不是一个节点,那么就要把一个数当成另一个数的父节点,要减去一条线(因为是题目给的两个点,连上就说明少了一条)
#include<iostream>
using namespace std;
int main(){
int t;
cin>>t;
int ans=0;
int r,l;int a,b;
while(t--){
cin>>l>>r;
if(r/2+1>=l){
a=r/2+1;
b=r;
}
else{
a=l;
b=r;
}
ans=b%a;
cout<<ans<<endl;
}
return 0;
}
r的值是定的,b=r;
r/2+1>l,a=r/2+1;
else a=l;
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int main(){
string a,b;
cin>>a>>b;
int cnt4=0,cnt7=0;
for(int i=0;i<a.length();i++){
if(a[i]!=b[i]&&a[i]=='4') cnt4++;
if(a[i]!=b[i]&&a[i]=='7') cnt7++;
}
cout<<max(cnt4,cnt7)<<endl;
return 0;
}
就是找4和7一共有多少可以互换,剩下不能凑在一起的就转换