1. 程式人生 > >【題解】兩個數

【題解】兩個數

描述 整數 請求 clas mem 變化 程序 time 輸入

題目描述

現有兩個人,若第一個人當前手中的數為w1,則下一秒他手上的數將會變成(x1×w1+y1)mod m;若第二個人當前手中的數為w2,則下一秒他手上的數將會變為(x2×w2+y2)mod m(a mod b表示a除以b的余數)。第0秒,兩個人手上的數分別為h1,h2;請求出最快在第幾秒,第一個人手上的數為a1,且第二個人手上的數為a2。若不可能,則輸出-1。

輸入輸出格式

輸入格式

第一行為一個正整數T,表示數據組數。

對於接下來的每一組數據,第一行為一個正整數m,第二行包括兩個整數h1,a1,第三行包括 兩個整數x1,y1,第四行包括兩個整數h2,a2,第五行包括兩個整數x2,y2。

輸出格式

對於每一組數據,輸出一行,一個整數,如題所述。

輸入輸出樣例

輸入樣例

2

5

4 2

1 1

0 1

2 3

1023

1 2

1 0

1 2

1 1

輸出樣例

3

-1

說明

數據規模

對於30%的數據,m≤1000;

對於100%的數據,T≤5,h1不等於a1且h2不等於a2,2≤m≤10^6,0≤h1,a2,x1,y1,h2,a2,x2,y2<m。

題解

此題的關鍵在於找h變化的循環節,暴力查找即可。找到之後就判斷循環節組合起來是否長度相同即可。具體看程序理解。

技術分享圖片
#include <iostream>
#include <cstring>

#define MAXM 1000000

using namespace std;

int T;
long long m;
long long h, a, x, y;
long long num[2][2];
int b[MAXM];

int main()
{
    cin >> T;
    while(T--)
    {
        cin >> m;
        for(register int i = 0; i < 2
; ++i) { cin >> h >> a >> x >> y; num[i][0] = 0; num[i][1] = 1; if(h != a) { memset(b, 0, sizeof(int) * m); b[h] = 1; while(h != a) { ++num[i][0]; h = (h * x + y) % m; if(b[h]) { num[i][0] = -1; break; } b[h] = 1; } } memset(b, 0, sizeof(int) * m); h = (h * x + y) % m; b[h] = 1; while(h != a) { ++num[i][1]; h = (h * x + y) % m; if(b[h]) { num[i][1] = -1; break; } b[h] = 1; } } if(num[0][0] == -1 || num[1][0] == -1) cout << -1; else if(num[0][0] == num[1][0]) cout << num[0][0]; else if(num[0][1] == -1 && num[1][1] == -1) cout << -1; else if(num[0][1] == -1) { if(num[0][0] < num[1][0]) cout << -1; else if((num[0][0] - num[1][0]) % num[1][1]) cout << -1; else cout << num[0][0]; } else if(num[1][1] == -1) { if(num[1][0] < num[0][0]) cout << -1; else if((num[1][0] - num[0][0]) % num[0][1]) cout << -1; else cout << num[1][0]; } else { long long g1 = num[0][1], g2 = num[1][1], g3; while(g2) { g3 = g1 % g2; g1 = g2; g2 = g3; } if((num[0][0] - num[1][0]) % g1) cout << -1; else for(register int i = 0; ; ++i) { if(num[0][0] + num[0][1] * i < num[1][0]) continue; if(!((num[0][0] + num[0][1] * i - num[1][0]) % num[1][1])) { cout << num[0][0] + num[0][1] * i; break; } } } cout << "\n"; } return 0; }
參考程序

【題解】兩個數