數論Day3 進製問題 題解

2021-08-01 23:47:05 字數 4283 閱讀 8423

數論進入第三天,進製問題是常用提醒,是數論的乙個重要知識點,常考!

題面:

首先明確資料範圍:

【資料規模和約定】

對於40%的資料,

a的長度不超過5。

對於100%的資料,

a的長度不超過

100000

。 對於40%暴力列舉不多說,上**:

var t,i,k,tt:longint;

a:qword;

s:string;

function pow(x,n:qword):qword;

begin

if n=0 then exit(1);

pow:=pow(x,n>>1);

pow:=pow*pow;

if n mod 2=1 then pow:=(pow*x);

end;

function f(s:string):qword;

var tx,i:longint;

w:array[0..5]of longint;

x:qword;

begin

fillchar(w,sizeof(w),0);

w[0]:=length(s);

for i:=1 to length(s) do begin

if (s[i]<='9')and(s[i]>='0') then

w[i]:=ord(s[i])-ord('0')

else w[i]:=ord(s[i])-ord('a')+10;

end;

x:=0;

tx:=w[0]-1;

for i:=1 to w[0] do begin

x:=x+pow(k,tx)*w[i]; dec(tx); end;

exit(x);

end;

begin

assign(input,'kbased.in');

assign(output,'kbased.out');

reset(input);

rewrite(output);

readln(t);

for i:=1 to t do begin

readln(k);

readln(s);

a:=f(s);

if a mod (k-1)=0 then writeln('yes')

else writeln('no');

end;

end.

40分非常妥!

但是:對於100%的資料,

a的長度不超過

100000。

怎麼處理?

思考乙個問題:每乙個k進製數可以表示為什麼?

●任何乙個k進製正整數都可以寫成:a0*k0+a1*k1+…+an*kn

這是初賽的內容吧,相信來看題解的人這點心中自然明確。

對於幾乎要達到線性的時間複雜度來說,必須要從kn

這裡下手!

那麼來看乙個非常簡單的例子:

∵k0=1,∴ k0 mod (k-1) = 1;

∵k1=k-1+1,∴ k1 mod (k-1) = 1;

∵k2 = k*k,∴ k2 mod (k-1) = 1;

●所以推出:kn = kn-1*k,kn mod (k-1) = 1

沒問題吧?

●任何乙個k

進製正整數都可以寫成:a0*k

0+a1*k

1+…+an*k

n 又因為所有的k?模k-1都是1(?是乙個常數)

所以任何乙個k進製正整數,模k-1的結果,都等於它各個數字上數字之和模k-1。

【程式】

var  w:array[0..100000]of longint;

t,i,k:longint;

s:ansistring;

a:qword;

function f(s:ansistring):qword;

var i:longint;

ans:qword;

begin

fillchar(w,sizeof(w),0);

w[0]:=length(s);

ans:=0;

for i:=1 to length(s) do begin

if (s[i]<='9')and(s[i]>='0') then

w[i]:=ord(s[i])-ord('0')

else w[i]:=ord(s[i])-ord('a')+10;

inc(ans,w[i]);

end;

exit(ans);

end;

begin

assign(input,'kbased.in');

assign(output,'kbased.out');

reset(input);

rewrite(output);

readln(t);

for i:=1 to t do begin

readln(k);

readln(s);

fillchar(w,sizeof(w),0);

a:=f(s);

if a mod (k-1)=0 then writeln('yes')

else writeln('no');

end;

close(input);

close(output);

end.

暴力出奇蹟:

20%:

n<=1000

另外20%:只有0和

1 不解釋o(n^2);

非暴力出滿分:

【樣例分析】

and去運算:

0 and 0=0  0 and 1=0  1 and 0=0  1 and 1=1 第1

與第2數

第1與第3數

第2與第3

數 舉例:5 and 23

1 and 2

1 and 1

2 and 1

and  10111

and  10

and  01

and  01

最大數為1 and 1=1。

另外幾個數字!

舉例:4個數

11 6 10 8

1011

1010

1000

看出來了吧?

用1 2 4得出的數最大!

所以,可以用貪心來解決:為使兩數的and最大,故從高位開始(從左向右

a<=10

9:31位到

0位)列舉,看第1列的

1個數有否大於等於

2個;若找到,則將其它第1列為

0的設為不可用

(vis[max_n])

。繼續找後面位也同樣處理。

取第i位是否為1:

a[j]>>i mod 2=1

。同理第

i位是否為

1: a[j]>>i mod 2=0;

答案為ans:=ans+(1<

var n,i,j,ans,cnt:longint;

a:array[1..100000]of longint;

u:array[1..100000]of boolean;

begin

assign(input,'and.in');

assign(output,'and.out');

reset(input);

rewrite(output);

readln(n);

fillchar(u,sizeof(u),true);

for i:=1 to n do read(a[i]);

for i:=31 downto 0 do begin

cnt:=0;

for j:=1 to n do begin

if (a[j]>>i mod 2=1)and(u[j]) then inc(cnt);

end;

if cnt>=2 then begin

ans:=ans+(1<>i mod 2=0 then u[j]:=false;

end;

end;

writeln(ans);

close(input);

close(output);

end.

日積月累 day3

sector 扇區,段 分段 vertically 豎直地,直立地 horizonally 水平地backspace 退格,回退 terminate 端接,終止 drag 拖,拉,牽,拽 formatted 有格式的 underscore 在.下面劃線 initially 最初,開頭 reforma...

QT程式設計 day3

當建立乙個專案之後,資料夾裡會有6個檔案。其中有乙個為.pro.user檔案,這個檔案不屬於專案源 的一部分,它是qtcreator專屬的使用者定製專案設定,儲存了這個專案本地化的設定。qtcreator開啟專案時會讀取這個設定檔案,比較該專案裡的檔案配置與當前的專案位置等是否符合,符合就載入配置,...

北京集訓DAY3

消去合法的序列 剩下的不合法序列一定是 3兩種括號個數各加1除2 手算一下即可4 5 include 6 include 7 include 8 9const int maxn 100010 10 11int len,top,cnt 1213 char s maxn 1415 inthh 25int...