http://www.bnuoj.com/bnuoj/problem_show.php?pid=4357
【题意】:在1000个数中选择3个之和是m的倍数,可能有多种选择方案,请输出标号排序最小的一组,并且三个标号按升序输出
【题解】:三层循环,转化成两层循环
先将1000个数对m取余,存入mod数组,表示是否存在,并对该余数出现的位置进行标记保存,两层循环遍历两个数,用m-这两个数之和,看是否存在mod中,并且位置没有在之前的循环i、j中出现就可以。。。
【code】:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <vector> 6 7 using namespace std; 8 9 int arr[1010],mod[10010]; 10 vector<int> G[10010]; 11 12 int isOK(int temp,int x,int y) 13 { 14 int i; 15 for(i=0;i<G[temp].size();i++) 16 { 17 //cout<<temp<<" "<<G[temp][i]<<" "<<x<<" "<<y<<endl; 18 if(G[temp][i]!=x&&G[temp][i]!=y) 19 { 20 return i; 21 } 22 } 23 return -1; 24 } 25 26 int main() 27 { 28 int n,m; 29 scanf("%d%d",&n,&m); 30 int i,j; 31 memset(mod,0,sizeof(mod)); 32 for(i=0;i<=m;i++) G[i].clear(); 33 for(i=0;i<n;i++) 34 { 35 scanf("%d",arr+i); 36 arr[i]%=m; 37 mod[arr[i]]++; 38 // if(mod[arr[i]]==1) pos[arr[i]]=i; 39 G[arr[i]].push_back(i); 40 } 41 int flag = 0; 42 for(i=0;i<n;i++) 43 { 44 for(j=i+1;j<n;j++) 45 { 46 int temp = ((m-arr[i]-arr[j])+m)%m; 47 if(mod[temp]>=1) 48 { 49 int id = isOK(temp,i,j); 50 if(id!=-1) 51 { 52 printf("%d %d %d ",i+1,j+1,G[temp][id]+1); 53 flag=1; 54 break; 55 } 56 } 57 } 58 if(flag) break; 59 } 60 if(!flag) puts("-1"); 61 62 63 return 0; 64 }