題目描述
麥克在第一張紙上寫下了N個十進制實數。然後,對於每個實數,他都寫下了一個從0開始,以該數爲公差的等差數列。比如當前數爲x,則他寫的等差數列爲0,x,2x,3x,……接下來,他把第一張紙上的所有在區間[A,B]中的數挑選出來,剔除掉重複的,按升序寫在第二張紙上。但第二天,他把第一張紙弄丟了。現在,他請你根據第二張紙還原出第一張紙上的內容。
輸入
第一行包含一個自然數K,(K<=50),表示在第二張紙上有K個數。這些數都是在區間[A,B]之間的。第二行兩個整數A和B(1<=A<B<=106)接下來K行,每行一個實數,按升序排列。每個數最多5位小數。
輸出
N行,每行一個數。表示第一張紙上最開始的N個數。按升序排列。如果有多種可能,則輸出個數最少的一種,如果還有多種,任意輸出一種即可。
樣例輸入
4
1 2
1
1.4
1.5
2
樣例輸出
0.5
0.7
題解:
因爲最多5位小數,就可以先把每個數乘上100000,輸出答案的時候再除回來,方便計算。
首先尋找所有可能合法的差值。然後逐個枚舉,看在當前差值下是否可以組成合法數列。
最後檢驗每個差值是否多餘,刪去多餘的差值。
詳見代碼。
#include<cstdio> #include<algorithm> #include<map> using namespace std; typedef long long LL; const int N=55; const int M=1500; int n; LL A, B, num[N]; void Getin( LL &shu ) { char c; int f=5; shu=0; for( c=getchar(); c<'0' || c>'9'; c=getchar() ); for( ; c>='0' && c<='9'; c=getchar() ) shu=shu*10+c-'0'; if( c=='.' ) for( c=getchar(); c>='0' && c<='9'; c=getchar() ) shu=shu*10+c-'0', f--; while( f-- ) shu*=10; } map< LL, int >id; LL d[M], dcnt, ans[N], acnt; int way[N], cnt[N]; void Find_way( LL d ) { LL l=A, wcnt=0; if( A%d ) l=(A/d+1)*d; for( LL v=l; v<=B; v+=d )//尋找可能的數列 if( !id[v] ) return;//數列不合法 else way[++wcnt]=id[v]; bool flg=0; for( int i=1; i<=wcnt; i++ )//只要該數列的一個數未在之前的數列中出現過, 該數列有存在的意義 if( !cnt[ way[i] ] ) { flg=1; break; } if( !flg ) return; ans[++acnt]=d; for( int i=1; i<=wcnt; i++ ) cnt[ way[i] ]++; } void Judge( int i, LL d ) { LL l=A; if( A%d ) l=(A/d+1)*d; bool flg=0; for( LL v=l; v<=B; v+=d )//若該數列的所有數都在之前出現過不止一次, 該數列沒有存在的意義 if( cnt[ id[v] ]==1 ) { flg=1; break; } if( !flg ) ans[i]=0; } int main() { scanf( "%d", &n ); Getin(A); Getin(B); for( int i=1; i<=n; i++ ) { Getin( num[i] ); id[ num[i] ]=i; for( int j=0; j<i; j++ ) d[++dcnt]=num[i]-num[j];//找可能的差值 } sort( d+1, d+dcnt+1 ); dcnt=unique( d+1, d+dcnt+1 )-d-1; for( int i=1; i<=dcnt; i++ ) { bool flg=0; for( int j=1; j<=acnt; j++ )//該差值是之前某一合法差值的的倍數, 肯定不優 if( !( d[i]%ans[j] ) ) { flg=1; break; } if( !flg ) Find_way( d[i] ); } for( int i=1; i<=acnt; i++ ) Judge( i, ans[i] ); for( int i=1; i<=acnt; i++ ) if( ans[i] ) printf( "%.5lf\n", 1.0*ans[i]/1e5 ); return 0; }
[NOIP模擬賽]等差數列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.