QFNU 10-09 training
题意:就是给出了两个数组,然后第一组数中找到i,j,k满足i<j<k,第二组数中找到a[i],a[j],a[k],满足a[i]<a[j]<a[k],问找到这两组数之后,最小的a[i]+a[j]+a[k]的值是多少
思路:直接进行遍历寻找即可,从第一个for循环中进行两个不同的for循环,找到其左边和右边最小的值
代码:

1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 using namespace std; 7 int main(){ 8 int n; 9 scanf("%d",&n); 10 11 int s[n+2]; 12 int c[n+2]; 13 for(int i=0;i<n;i++){ 14 scanf("%d",&s[i]); 15 16 } 17 for(int i=0;i<n;i++){ 18 19 scanf("%d",&c[i]); 20 21 } 22 long long int minn=1000000000; 23 int flag1=0,flag2=0; 24 int f,ff; 25 for(int i=1;i<n-1;i++){ 26 27 long long int minn1=1000000000,minn2=1000000000; 28 29 for(int j=0;j<i;j++){ 30 if(s[j]<s[i]&&(c[i]+c[j])<minn1){ 31 minn1=c[i]+c[j]; 32 flag1=1; 33 f=j; 34 } 35 } 36 for(int j=i+1;j<n;j++){ 37 if(s[i]<s[j]&&c[j]<minn2){ 38 minn2=c[j]; 39 flag2=1; 40 ff=j; 41 } 42 } 43 if((minn1+minn2)<minn&&flag1==1&&flag2==1){ 44 45 minn=minn1+minn2; 46 } 47 } 48 if(minn==1000000000){ 49 printf("-1\n"); 50 }else{ 51 printf("%lld",minn); 52 } 53 54 }
2.链表去重
思路:输入链表的元素之后,用另一个数组将其分开,直接按照key是否重复分成x与y组,进行存贮其address即可,再通过格式要求进行输出
代码:

1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 using namespace std; 7 const int maxx=1e6+2; 8 struct num{ 9 int address,key,next; 10 int num=4; 11 }a[maxx],p[maxx]; 12 int sum[maxx]={0}; 13 int x[maxx],y[maxx]; 14 int main(){ 15 int start,n; 16 scanf("%d %d",&start,&n); 17 int starti=start; 18 for(int i=0;i<n;i++){ 19 int address=0; 20 scanf("%d",&address); 21 scanf("%d %d",&p[address].key,&p[address].next); 22 } 23 int i=0; 24 int j1=0,j2=0; 25 while(starti!=-1){ 26 int s=fabs(p[starti].key); 27 if(sum[s]==0){ 28 sum[s]++; 29 x[j1]=starti; 30 j1++; 31 }else{ 32 y[j2]=starti; 33 j2++; 34 } 35 starti=p[starti].next; 36 } 37 38 39 for(int i=0;i<j1-1;i++){ 40 printf("%05d %d %05d\n",x[i],p[x[i]].key,x[i+1]); 41 } 42 printf("%05d %d -1\n",x[j1-1],p[x[j1-1]].key); 43 for(int i=0;i<j2-1;i++){ 44 printf("%05d %d %05d\n",y[i],p[y[i]].key,y[i+1]); 45 } 46 if(j2>=1){ 47 printf("%05d %d -1\n",y[j2-1],p[y[j2-1]].key); 48 } 49 }
3.部落
思路:用并查集找到根节点,并且给他们进行合并,然后再进行寻找根节点是否是同一个
代码:

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxx=1e5; 7 int fa[maxx]; 8 int findd(int x){ 9 if(x==fa[x]){ 10 return x; 11 }else{ 12 return fa[x]=findd(fa[x]); 13 } 14 } 15 void unionn(int x,int y){ 16 int xx=findd(x); 17 int yy=findd(y); 18 if(xx!=yy){ 19 fa[xx]=yy; 20 } 21 } 22 int main(){ 23 int n; 24 scanf("%d",&n); 25 for(int i=0;i<maxx;i++){ 26 fa[i]=i; 27 } 28 int maxxx=0; 29 while(n--){ 30 int k; 31 scanf("%d",&k); 32 int y; 33 scanf("%d",&y); 34 maxxx=max(maxxx,y); 35 36 for(int i=0;i<k-1;i++){ 37 int x; 38 scanf("%d",&x); 39 maxxx=max(maxxx,x); 40 unionn(y,x); 41 } 42 } 43 int sum=0; 44 for(int i=1;i<=maxxx;i++){ 45 if(fa[i]==i){ 46 sum++; 47 } 48 } 49 printf("%d %d\n",maxxx,sum); 50 int kk; 51 scanf("%d",&kk); 52 while(kk--){ 53 int x,y; 54 scanf("%d %d",&x,&y); 55 if(findd(x)==findd(y)){ 56 printf("Y\n"); 57 }else{ 58 printf("N\n"); 59 } 60 } 61 }
4.月饼
思路:直接比较单价就可以
代码:

1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 using namespace std; 7 struct num{ 8 double numm; 9 double money; 10 double m; 11 }s[2000]; 12 bool cmp(num& a,num& b){ 13 return a.m>b.m; 14 } 15 int main(){ 16 int n,d; 17 scanf("%d %d",&n,&d); 18 for(int i=0;i<n;i++){ 19 scanf("%lf",&s[i].numm); 20 } 21 for(int i=0;i<n;i++){ 22 scanf("%lf",&s[i].money); 23 s[i].m=s[i].money*1.0/s[i].numm; 24 } 25 double sum=0,ns=0; 26 sort(s,s+n,cmp); 27 28 for(int i=0;i<n;i++){ 29 if(d>=s[i].numm){ 30 sum+=s[i].money; 31 d-=s[i].numm; 32 }else if(d>=0){ 33 sum+=s[i].m*d; 34 break; 35 } 36 } 37 printf("%.2f\n",sum); 38 }