時間限制:2000ms
單點時限:
1000ms
記憶體限制:
256mb
大神同學是乙個熱愛數字的孩子,她無時無刻不在思考生活與數學的聯絡。有一天,她發現其實公曆的設計是有講究的。
每4年就會多閏一天,每一百年又會有一年不是閏年,而第四百年又是閏年。這樣,這四百年的週期裡每一年平均有365又400分之97天。
大神同學將上面的規律簡記為100-4+1=97。
大神同學想知道是不是每乙個自然數都能按照上面的形式表示出來,具體來說就是,大神同學希望將乙個自然數n寫成a1 - a2 + a3 - a4 + …的形式,其中
a1是a2的倍數,a2是a3的倍數,依此類推。另外,大神同學不想讓這個問題變得太無聊,她還增加了一些附加條件:
1. 其中ai ≠ aj (i ≠ j),即相鄰的兩個數前乙個至少是後乙個的兩倍或以上。
2. 數列的長度至少為3,不能超過100(大神同學覺得數列太長一定可以找到答案)。
3. 構造出來的數列中的每乙個數不能太大,因此大神同學希望數列中的每乙個數都是小於263的正整數。
大神同學思考了一會兒,發現這個問題似乎沒有那麼簡單,現在她求助於你,希望你能幫她解決這個不太簡單的問題。
第一行包括乙個數t,表示資料的組數。
接下來包含t組資料,每組資料一行,包括乙個整數n。
對於每組資料,輸出一行「case x: 」,其中x表示每組資料的編號(從1開始),後接乙個字串「no solution」表示無解,或者輸出一列數,相鄰兩個數之間用空格隔開。如果有多組數列滿足要求,輸出任意一組。
小資料:
1 ≤ t ≤ 10
1 ≤ n ≤ 100
大資料:
1 ≤ t ≤ 1000
1 ≤ n ≤ 1018
樣例輸入
2197
樣例輸出
case 1: no solutioncase 2: 100 4 1
思路:
根據題目要求,我們可以對分解後的數列不斷提取公因子,表達成如下形式,
n = (…((k1-1)k2+1)k3-1)…)ai
那麼,a1 = k1*k2…*ki-1*ai
a2 = k2*k3…*ki-1*ai
……ai-1 = ki-1*ai
然後,我們遍歷k1…ki-1的可能取值來找出所有符合條件的數列,本題中只要求輸出乙個即可。
從k1開始遍歷,在遍歷過程中,計算每乙個字首串的值,然後用這個值來縮小後續遍歷的範圍。
比如,對於kj,字首串的取值為pre = (…((k1-1)k2+1)k3-1)…)kj-1+(-1)^(j-1)
那麼kj的範圍為[2,n/pre]。如果n%(pre*kj+(-1)^j)=0,那麼停止該串的遍歷,即找到了乙個符合條件的數列。
**實現:
#include using namespace std;int isfound,ii;
unsigned long long a[100];
unsigned long long k[100];
unsigned long long n;
void prefix(unsigned long long pre,int dep)
else if(dep<100)
prefix(pre,dep+1);
else
break;
if(isfound)
break;}}
int main()
isfound = 0;
ii = 0;
for(k[0]=2;k[0]<=(n+1)/2;k[0]++)
count++;
cout<<"case "for(i=0;i
cout<}
else
}return 0;
}
HDU 5821(乙個數列變換成另乙個數列)
a 4 6 5 9 b 5 6 9 4 以上兩個數列a和b,問你可以通過交換a中數的位置實現a變成b數列嗎?解決方法 把a中每個值應該放在位置的左邊寫出,對應如下 a 4 6 5 9 mov 4 2 1 3 表示應該放的位置 然後把 4,2,1,3 排一下序得到1 2 3 4正好與原先遍歷a陣列的循...
輸出乙個數列的逆序數
1,這個問題演算法導論講歸併排序時,提到過。找到乙個實現 思路還是蠻清晰的。核心 對於兩個有序序列,找逆序對,遍歷一次即可。2,實現 include include using namespace std int inv int data,int n ret j tmp i j data i 不是逆...
實現長連線的乙個思路
要做乙個訊息功能,在網上找了乙個實現長連線比較簡單的方式,通過發請求超時後再重新發請求,收到請求保持到符合某條件在響應的方式。乙個php的例子 demo.html comet test chat backend.php filename dirname file data.txt 訊息都儲存在這個檔...