1.权势二进制
题目:
一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。输入:
k组测试数据。输出:
输出答案占k行。每行为每个n的答案。
数据范围:
第1行给出一个整数k (1<=k<=10)
第2到k+1行每行一个整数n(1<=n<=1000000)
思路:
答案就是n中最大的位,原因就是只要保证最大的位了,其他的就可以写出来了,因为如果要加1位,那么剩余的每一位都可以+1。
时间复杂度n的十进制位数
Code:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<cmath>
using namespace std;
int ans = 0;
int read()
{
int ret = 0;
int w = 1;
char ch = getchar();
while(ch > '9' || ch < '0')
{
if(ch == '-')
w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
ret = (ret << 3) + (ret << 1) + ch - '0',ch = getchar();
return ret * w;
}
void print(int x)
{
if(x < 0)
putchar('-'),x = -x;
if(x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
int main()
{
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
int ans = 0,n;
int k;
k = read();
for(int i = 1;i <= k;i++)
{
ans = 0;
n = read();
while(n)
{
ans = max(ans,n % 10);
n /= 10;
}
print(ans);
puts("");
}
}
2.num
题目:
KC邀请他的两个小弟K和C玩起了数字游戏。游戏是K和C轮流操作进行的,K为先手。KC会先给定一个数字Q,每次操作玩家必须写出当前数字的一个因数来代替当前数字,但是这个因数不能是1和它本身。例如当前数字为6,那么可以用2,3来代替,但是1和6就不行。现在规定第一个没有数字可以写出的玩家为胜者。K在已知Q的情况,想知道自己作为先手能不能胜利,若能胜利,那么第一次写出的可以制胜的最小数字是多少呢?整个游戏过程我们认为K和C用的都是最优策略。输入:
只包括一个正整数Q输出:
第一行是1或2,1表示K能胜利,2表示C能胜利。若K能胜利,则在第二行输出第一次写出的可以制胜的最小数字,若是第一次就无法写出数字,则认为第一次写出的可以制胜的最小数字为0。
说明:若C能胜利,不用输出第二行,输出2即可。
数据范围:
对于30%的数据,Q<=50; 对于100%的数据,Q<=10^13。
思路:
1.Q是1或质数,此时小K只能选0,胜利。2.Q是两个质数的积,小K只能选这两个质数中的一个,对方无法写出,对方胜利。
3.Q是多个质数的积,小K有必胜策略,胜利。
(当Q = 2 * 2 * 3 = 12时,小K选4,对方选择2。小K无法选择,胜利)
Code:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<cmath>
#include<queue>
#define ll long long
using namespace std;
ll n,ans;
queue<ll>q;
int main()
{
//freopen("num.in","r",stdin);
//freopen("num.out","w",stdout);
cin >> n;
for(ll i = 2;i * i <= n;i++)
while(n % i == 0)
q.push(i),n /= i;
if(n != 1)
q.push(n);
if(q.size() == 2)
printf("2\n");
else if(q.size() == 1)
printf("1\n0\n");
else
{
printf("1\n");
ans = q.front();
q.pop();
printf("%lld\n",ans * q.front());
}
return 0;
}
3.复仇者vsX战警之训练
题目:
月球上反凤凰装甲在凤凰之力附身霍普之前,将凤凰之力打成五份,分别附身在X战警五大战力上面辐射眼、白皇后、钢力士、秘客和纳摩上(好尴尬,汗)。在凤凰五使徒的至高的力量的威胁下,复仇者被迫逃到昆仑的一座山上,因为凤凰五使徒监视不到那里。
霍普加入了复仇者,为了磨练自己,她在n个山峰之间跳跃。
这n个山峰在一条直线上,每个山峰都有不同的高度,只知道这些山峰在水平上相对位置。霍普可以将这些山峰左右移动但不能改变他们的相对位置(要保证两两山峰间距为整数且大于等于1)。霍普要从最矮的山峰开始跳,每次跳向第一个比现在她所在的山峰高的山峰,一共跳n-1次,由于能力有限,每次跳跃的水平距离小于等于d。
霍普想知道如何移动这些山峰,使得在可以经过所有的山峰并跳到最高的山峰上的基础下,又要使最矮的山峰和最高的山峰的水平距离最远,霍普要你求出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。
输入:
本题每个测试点有多组数据,在第一行中有一个整数t,表示数据的数目
对于每组数据:
第一行包含两个整数n和d
下一行包含n个整数,给出n个山峰的高度,输入顺序即为山峰在水平上的相对顺序。在每个数据中,所有的高度都是唯一的。
输出:
扫描二维码关注公众号,回复:
3620243 查看本文章
输出共t行。对于每组数据输出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。
数据范围:
对于100%的数据,1≤n≤1000,1≤d≤1000000,t<=500
思路:
差分约束系统把这道题目分解,可以分解为两个条件。
1、两个山峰之间水平距离至少为1(因为山峰不能再同一位置上)。
2、霍普每次最多跳d的水平距离。
对于第一个条件,对于两个相邻的山峰,相对位置(即输入顺序)大的向相对位置小的连一条-1的边。
对于第二个条件,对于两个高度排名相邻的山峰,相对位置小的向相对位置大的连一条d的边。
然后比较最高和最低的山峰,从相对位置小的那个山峰出发,做一次最短路,输出到相对位置大的山峰的距离。
Code:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
const long long maxlongint = 2147483647;
const long long mo = 1000000007;
const long long N = 2005;
using namespace std;
struct ddx
{
int h,p;
}a[N];
int T,last[N * 2],to[N * 2],ne[N * 2],v[N * 2],dis[N],n,dd,tot,d[N * N],pp,num[N];
bool bz[N];
inline int read()
{
int ret = 0,w = 0;
char ch = 0;
while(!isdigit(ch))
{
w |= ch == '-';
ch = getchar();
}
while(isdigit(ch))
{
ret = (ret << 3) + (ret << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -ret : ret;
}
inline void write(int ret)
{
if(ret < 0)
{
putchar('-');
ret = -ret;
}
if(ret > 9)
write(ret / 10);
putchar(ret % 10 + '0');
}
void bj(int x,int y,int z)
{
ne[++tot] = last[x];
last[x] = tot;
to[tot] = y;
v[tot] = z;
}
bool cmp(ddx x,ddx y)
{
return x.h < y.h;
}
int spfa(int x)
{
memset(bz,true,sizeof(bz));
fill(dis,dis + 1 + n,1200000000);
memset(num,0,sizeof(num));
int head = 0,tail = 1,g;
dis[x] = 0;
d[1] = x;
while(head < tail)
{
g = d[++head];
bz[g] = true;
for(register long long i = last[g];i;i = ne[i])
{
long long j = to[i];
if(dis[j] > dis[g] + v[i])
{
dis[j] = dis[g] + v[i];
if(bz[j])
{
bz[j] = false;
d[++tail] = j;
if(++num[j] > n)
return -1;
}
}
}
}
return 0;
}
int main()
{
T = read();
while(T--)
{
pp++;
n = read();
dd = read();
tot = 0;
memset(last,0,sizeof(last));
memset(ne,0,sizeof(ne));
memset(to,0,sizeof(to));
memset(v,0,sizeof(v));
for(int i = 1;i <= n;i++)
{
a[i].h = read();
a[i].p = i;
bj(i,i - 1,-1);
}
sort(a + 1,a + 1 + n,cmp);
for(int i = 1;i <= n - 1;i++)
{
if(a[i].p < a[i + 1].p)
bj(a[i].p,a[i + 1].p,dd);
else
bj(a[i + 1].p,a[i].p,dd);
}
int e,k;
if(a[1].p < a[n].p)
{
k = spfa(a[1].p);
e = a[n].p;
}
else
{
k = spfa(a[n].p);
e = a[1].p;
}
if(k == -1)
{
write(-1);
puts("");
}
else
{
write(dis[e]);
puts("");
}
}
}
4.游戏
题目:
Guyu Guo和Tube Lu正在玩一个游戏:Lu默想一个1和n 之间的数x,然后Guo尝试猜出这个数。Guo能提出m个这样的问题: “未知数是否能被yi整除?”
游戏按照如下流程进行:Guo先给出他想问的全部m个问题,然后Lu对所有问题依次以“是”或“否”作答。得到m个问题的答案之后,Guo就要给出他的猜测。
Guo写了一个程序帮他以最优的方式提出这m个问题,现在他想知道在保证得到一个确定的答案下,最少可以问多少个问题,即m的最小值。但是Guo正忙于吃漂亮学姐送他的糖果而无暇改代码(送糖果的学姐十分多,以至于有许多糖果快要过期了),所以他找到了你,希望你来帮他解决这个问题。
输入:
一行,一个整数n
输出:
一行,一个整数m
数据范围:
对于20%的数据:1 ≤ n ≤ 20
对于60%的数据:1 ≤ n ≤ 1000
对于100%的数据: 1 ≤ n ≤ 100000
思路:
由于一次性提出m个问题,然后得到回答,所以只能通过问题来确定最终可能的所有情况。考虑一个数的质因子分解,n=2^X1*3^X2*5^X3....即要确定所有质数可能出现的次数,所以答案为所有质数的幂次<=n的个数Code:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cctype>
#include<cmath>
using namespace std;
bool f[100010];
long long w;
int n,ans;
inline int read()
{
int ret = 0,w = 0;
char ch = 0;
while(!isdigit(ch))
{
w |= ch == '-';
ch = getchar();
}
while(isdigit(ch))
{
ret = (ret << 3) + (ret << 1) + (ch ^ 48);
ch = getchar();
}
return w ? -ret : ret;
}
inline void write(int ret)
{
if(ret < 0)
{
putchar('-');
ret = -ret;
}
if(ret > 9)
write(ret / 10);
putchar(ret % 10 + '0');
}
int main()
{
//freopen("game.in","r",stdin);
//freopen("game.out","w",stdout);
n = read();
memset(f,false,sizeof f);
f[1] = true;
ans = 0;
for(int i = 2;i <= n;i++)
if(f[i] == false)
for(int j = 2;j <= n / i;j++)
f[i * j] = true;
for(int i = 2;i <= n;i++)
if(f[i] == false)
{
w = i;
while(w <= n)
{
ans++;
w *= i;
}
}
write(ans);
}