题目描述:山中有M个山洞,成环形,编号为1~M,(0<M<100000),有n(0<n<100)个野人分别住在编号为c1,c2,c3....cn的山洞中,每年野人都按顺时针方向移动p1,p2,p3...pn个山洞,第i个野人的寿命为li,要使野人在有生之年都不会相遇,最小的M值,若M有解,输出解,否则输出"NO"。
分析:
对于确定的M值,若有(c[i]+p[i]*l)%M==(c[j]+p[j]*l)则野人i,j就会在第l年相遇。所以要使i,j两野人在他们有生之年不相遇则应满足:在最先死去的那个野人的有生之年他们不能相遇。所以l取遍0~min(l[i],l[j]) 都有(c[i]+p[i]*l)%M!=(c[j]+p[j]*l).若所有的野人两两都不相遇,则M即为所求。
代码:
#include<iostream>
using namespace std;
int c[100],p[100],l[100];
int M;
int min(int a,int b){
return a<b?a:b;
}
int xiangrong(int i,int j){
int x,y;
y=min(l[i],l[j]);
for(x=0;x<=y;x++)
if((c[i]+p[i]*x)%M==(c[j]+p[j]*x)%M)
return 1;
return 0;
}
int main(){
int i,j,n,flag=0;
cin>>n;
for(i=0;i<n;i++)cin>>c[i];
for(i=0;i<n;i++)cin>>p[i];
for(i=0;i<n;i++)cin>>l[i];
for(M=n;M<=100000&&!flag;M++){
flag=1;
for(i=1;i<n&&flag;i++)
for(j=0;j<i&&flag;j++)
if(xiangrong(i,j))flag=0;
}
if(flag)cout<<M-1<<endl;
else cout<<"NO!"<<endl;
return 0;
}