T1.
权势二进制
题目大意:
给出K组数据,每组给出一个十进制整数N,做权势二进制是十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。
1<=k<=10
1<=n<=1000000
题解:
对于一个N,我们发现只需要找到他某个最大的数字X然后输出就可以了,因为可以用X-1去将他抵消(抵消过程中其他同样被抵消),然后每一位都在0~1,就可以全抵掉。
时间复杂度:O(length(N))
var
i,j,k,max:longint;
n:string;
begin
assign(input,'a.in'); reset(input);
assign(output,'a.out');rewrite(output);
readln(k);
for i:=1 to k do
begin
readln(n);
max:=0;
for j:=1 to length(n) do
if ord(n[j])-48>max then max:=ord(n[j])-48;
writeln(max);
end;
close(input);close(output);
end.
T2.
num:
题目大意:
对于一个数字游戏,K为先手。KC会先给定一个数字Q,每次操作玩家必须写出当前数字的一个因数来代替当前数字,但是这个因数不能是1和它本身。例如当前数字为6,那么可以用2,3来代替,但是1和6就不行。现在规定第一个没有数字可以写出的玩家为胜者。K在已知Q的情况,想知道自己作为先手能不能胜利,若能胜利,那么第一次写出的可以制胜的最小数字是多少呢?整个游戏过程我们认为K和C用的都是最优策略。
对于30%的数据,Q<=50
对于100%的数据,Q<=10^13
题解:
分情况讨论:
对于Q:
1:质数,writeln(1); write(0);
2:两个质数的乘积(两个质数可以相等),write(2)
3:n=k*t*t, t为此质因数的积,枚举找到T输出
var
i,num:longint;
j,k,n,m,ans:int64;
begin
assign(input,'num.in'); reset(input);
assign(output,'num.out');rewrite(output);
readln(n);
m:=n;
for i:=2 to trunc(sqrt(n)-0.1) do
while n mod i=0 do
begin
n:=n div i;
num:=num+1;
end;
if trunc(sqrt(n))=sqrt(n)
then inc(num);
n:=m;
if num=0
then begin
writeln(1);
writeln(0);
end
else if num=1
then writeln(2)
else begin
ans:=1;
for i:=2 to trunc(sqrt(n)) do
begin
k:=0;
while n mod i=0 do
begin
inc(k);
n:=n div i;
ans:=ans*i;
if ans<>i then
begin
writeln(1);
writeln(ans);
halt;
close(input); close(output);
end;
end;
end;
end;
close(input);close(output);
end.
T3.
复仇者vsX战警之训练:
霍普加入了复仇者,为了磨练自己,她在n个山峰之间跳跃。
这n个山峰在一条直线上,每个山峰都有不同的高度,只知道这些山峰的相对位置。霍普可以将这些山峰左右移动但不能改变他们的相对位置(要保证两两山峰间距为整数且大于等于1)。霍普要从最矮的山峰开始跳,每次跳向第一个比现在她所在的山峰高的山峰,一共跳n-1次,由于能力有限,每次跳跃的水平距离小于等于d。
霍普想知道如何移动这些山峰,使得在可以经过所有的山峰并跳到最高的山峰上的基础下,又要使最矮的山峰和最高的山峰的水平距离最远,霍普要你求出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。
题解:
差分约束系统:
把这道题目分解,可以分解为两个条件。
1、两个山峰之间水平距离至少为1(因为山峰不能再同一位置上)。
2、霍普每次最多跳d的水平距离。
对于第一个条件,对于两个相邻的山峰,相对位置(即输入顺序)大的向相对位置小的连一条-1的边。
对于第二个条件,对于两个高度排名相邻的山峰,相对位置小的向相对位置大的连一条d的边。
然后比较最高和最低的山峰,从相对位置小的那个山峰出发,做一次最短路,输出到相对位置大的山峰的距离。
var
s,t,w,next:array [0..5001] of longint;
list,sum,dis:array [0..1001] of longint;
a:Array [0..1001,1..2] of longint;
c:Array [0..10000001] of longint;
v:Array [0..1001] of boolean;
i,j,k,p,g,n,d:longint;
procedure qsort(l,r:longint);
var
i,j,mid:longint;
begin
if l>=r then exit;
mid:=a[(l+r) div 2,1];
i:=l; j:=r;
repeat
while a[i,1]<mid do inc(i);
while a[j,1]>mid do dec(j);
if i<=j then
begin
a[0,1]:=a[i,1];a[i,1]:=a[j,1];a[j,1]:=a[0,1];
a[0,2]:=a[i,2];a[i,2]:=a[j,2];a[j,2]:=a[0,2];
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
procedure spfa;
var
head,tail,i,j:longint;
begin
if a[1,2]>a[n,2]
then begin
j:=a[1,2];
a[1,2]:=a[n,2];
a[n,2]:=j;
end;
c[1]:=a[1,2];
dis[a[1,2]]:=0;
sum[a[1,2]]:=1;
v[a[1,2]]:=true;
head:=0;
tail:=1;
while head<tail do
begin
inc(head);
i:=list[c[head]];
while i>0 do
begin
if dis[s[i]]+w[i]<dis[t[i]]
then begin
dis[t[i]]:=dis[s[i]]+w[i];
sum[t[i]]:=sum[t[i]]+1;
if sum[t[i]]<n then
if not(v[t[i]])
then begin
v[t[i]]:=true;
inc(tail);
c[tail]:=t[i];
end;
end;
i:=next[i];
end;
v[c[head]]:=false;
end;
if (dis[a[n,2]]>0) and (dis[a[n,2]]<>10000001)
then writeln(dis[a[n,2]])
else writeln(-1);
end;
begin
assign(input,'attack.in'); reset(input);
assign(output,'attack.out');rewrite(output);
readln(g);
for k:=1 to g do
begin
fillchar(list,sizeof(list),0);
fillchar(next,sizeof(next),0);
fillchar(sum,sizeof(sum),0);
fillchar(v,sizeof(v),false);
p:=0;
readln(n,d);
for i:=1 to n do
begin
read(a[i,1]);
a[i,2]:=i;
dis[i]:=10000001;
end;
qsort(1,n);
for i:=1 to n-1 do
begin
inc(p);
s[p]:=i+1;t[p]:=i;w[p]:=-1;
next[p]:=list[s[p]];
list[s[p]]:=p;
inc(p);
if a[i,2]>a[i+1,2]
then begin
s[p]:=a[i+1,2];
t[p]:=a[i,2];
w[p]:=d;
next[p]:=list[s[p]];
list[s[p]]:=p;
end
else begin
s[p]:=a[i,2];
t[p]:=a[i+1,2];
w[p]:=d;
next[p]:=list[s[p]];
list[s[p]]:=p;
end;
end;
spfa;
end;
close(input); close(output);
end.
T4.