题目编号 | 标题 |
---|---|
0 | 权势二进制 |
1 | num |
2 | 复仇者vsX战警之训练(train) |
3 | 第四题 |
一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。
当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。
k组测试数据。
第1行给出一个整数k (1<=k<=10)
第2到k+1行每行一个整数n(1<=n<=1000000)
输出答案占k行。
每行为每个n的答案。
1
9
9
俗话说的好:样例都是骗人的
我想到的:打表加爆力
挂了
其实只要输出最大的那—位就行了
原因就是只要保证最大的位了,其他的就可以写出来了,因为如果要加1位,那么剩余的每一位都可以+1。时间复杂度n的十进制位数
#include
#include
using namespace std;
int n,m,k,f[1000100];
int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int t;
cin>>t;
while(t--){
cin>>n;
k=0;
while(n!=0){
if(n%10>k)k=n%10;
n=n/10;
}
cout<<k<<endl;
}
return 0;
}
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即可。
6
2
对于30%的数据,Q<=50; 对于100%的数据,Q<=10^13。
这题想一想,其实不难发现,自己获胜只能让对方给自己说一个质数,这时,我们想到了质因数分解,对方获胜只有我们给他说一个质数,所以我们只要判断n的质因数里是否存在2个以上的数
#include
#include
#include
using namespace std;
long long m,n,k,x,y;
int main(){
freopen("num.in","r",stdin);
freopen("num.out","w",stdout);
cin>>n;
k=1;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
k=0;
break;
}
}
if(k==1){
cout<<1<<endl<<0;
return 0;
}
y=10000000000000;
k=10000000000000;
x=2;
m=0;
long long m1=n;
while(x*x<=m1){
while(n%x==0){
if(x<y)y=x;
else if(x<k)k=x;
m++;
n=n/x;
if(m>2){
cout<<1<<endl<<y*k;
return 0;
}
}
x++;
}
if(m==2){
if(n!=1){
cout<<1<<endl<<y*k;
}
}
else
cout<<2;
return 0;
}
月球上反凤凰装甲在凤凰之力附身霍普之前,将凤凰之力打成五份,分别附身在X战警五大战力上面辐射眼、白皇后、钢力士、秘客和纳摩上(好尴尬,汗)。
在凤凰五使徒的至高的力量的威胁下,复仇者被迫逃到昆仑的一座山上,因为凤凰五使徒监视不到那里。
霍普加入了复仇者,为了磨练自己,她在n个山峰之间跳跃。
这n个山峰在一条直线上,每个山峰都有不同的高度,只知道这些山峰在水平上相对位置。霍普可以将这些山峰左右移动但不能改变他们的相对位置(要保证两两山峰间距为整数且大于等于1)。霍普要从最矮的山峰开始跳,每次跳向第一个比现在她所在的山峰高的山峰,一共跳n-1次,由于能力有限,每次跳跃的水平距离小于等于d。
霍普想知道如何移动这些山峰,使得在可以经过所有的山峰并跳到最高的山峰上的基础下,又要使最矮的山峰和最高的山峰的水平距离最远,霍普要你求出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。
输入文件名为attack.in。
本题每个测试点有多组数据,
在第一行中有一个整数t,表示数据的数目(t<=500)
对于每组数据:
第一行包含两个整数n(1≤n≤1000)和d(1≤d≤1000000)。
下一行包含n个整数,给出n个山峰的高度,输入顺序即为山峰在水平上的相 对顺序。在每个数据中,所有的高度都是唯一的。
输出文件名为attack.out。
输出共t行。
对于每组数据输出最远的水平距离。如果无论如何也不能经过所有的山峰并跳到最高的山峰上,那么输出-1。
3
4 4
20 30 10 40
5 6
20 34 54 10 15
4 2
10 20 16 13
3
3
-1
【数据说明】
对于100%的数据,1≤n≤1000,1≤d≤1000000
哇!刚看到题就被吓倒了,连暴力都不会打,骗分也不会骗,啥也没交
正解:SPFA+差分约束系统
思路:
把这道题目分解,可以分解为两个条件。
1、两个山峰之间水平距离至少为1(因为山峰不能再同一位置上)。
2、霍普每次最多跳d的水平距离。对于第一个条件,对于两个相邻的山峰,相对位置(即输入顺序)大的向相对位置小的连一条-1的边。对于第二个条件,对于两个高度排名相邻的山峰,相对位置小的向相对位置大的连一条d的边。然后比较最高和最低的山峰,从相对位置小的那个山峰出发,做一次最短路(小),输出到相对位置大的山峰的距离。
#include
#include
#include
#include
using namespace std;
long long m,n,k,x,y,d;
struct node{
int d,w;
}a[1001];
long long dis[1001],v[1001],f[1000010],r[1001];
int b[2001][5],tot,head[1001];
void ljb(int x,int y,int d){//邻接表
tot++;
b[tot][2]=y;
b[tot][3]=d;
b[tot][4]=head[x];
head[x]=tot;
}
bool cmp(node x,node y){
return x.d<y.d;
}
void spfa(int x,int gg){
memset(dis,1,sizeof(dis));
memset(v,0,sizeof(v));
memset(r,0,sizeof(r));
dis[x]=0;
f[1]=x;
v[x]=1;
int hd=0,tl=1;
while(hd<=tl){
hd++;
int x1=f[hd];
for(int i=head[x1];i;i=b[i][4]){
int y=b[i][2];
if(dis[y]>dis[x1]+b[i][3]){//确定方案
//大家会不会以为要的不是最大距离,而为啥这里是最小呢?
//应为你把它们山移动和其它山的距离也有关
//-1是让距离减到一个最大的位置
dis[y]=dis[x1]+b[i][3];
if(v[y]==0){
v[y]=1;
tl++;
f[tl]=y;
r[y]++;
if(r[y]>n){
cout<<-1<<endl;
return;
}//判断环
}
}
}
v[x1]=0;
}
if(gg==1)cout<<dis[a[n].w];
else cout<<dis[a[1].w];
cout<<endl;
}
int main(){
freopen("attack.in","r",stdin);
freopen("attack.out","w",stdout);
int t;
cin>>t;
while(t--){
memset(b,0,sizeof(b));
memset(head,0,sizeof(head));
tot=0;
cin>>n>>d;
for(int i=1;i<=n;i++){
cin>>a[i].d;
a[i].w=i;
ljb(i,i-1,-1);
}//相邻连-1
sort(a+1,a+1+n,cmp);
for(int i=1;i<n;i++){
if(a[i].w>a[i+1].w){
ljb(a[i+1].w,a[i].w,d);
}
else{
ljb(a[i].w,a[i+1].w,d);
}
}//大小相邻连d
if(a[1].w<a[n].w){
spfa(a[1].w,1);
}
else{
spfa(a[n].w,n);
}
}
return 0;
}
……