一步之遥
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
一步之遥
从昏迷中醒来,小明发现自己被关在 X 星球的废矿车里。 矿车停在平直的废弃的轨道上。 他的面前是两个按钮,分别写着 “F” 和“B” 。
小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。 按 F,会前进 97 米。按 B 会后退127 米。 透过昏暗的灯光,小明看到自己前方 1 米远正好有个监控探头。 他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。 或许,通过多次操作 F和 B 可以办到。
矿车上的动力已经不太足,黄色的警示灯在默默闪烁… 每次进行 F 或 B 操作都会消耗一定的能量。 小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方 1 米远的地方。
请问为了达成目标,最少需要操作的次数是多少。
分析:
方法一:暴力枚举F和B的次数
方法二:exgcd解方程
#include <bits/stdc++.h>
using namespace std;
int main()
{
int ans = 0x3f3f3f3f;
for(int i = 1; i <= 600; ++i)
{
for(int j = 1; j <= 600; ++j)
{
if(i * 97 - j * 127 == 1) ans = min(ans, i + j);
}
}
cout << ans << '\n';
return 0;
}
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include <iostream>
#define ll long long
using namespace std;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;y=0;
return a;
}
else
{
ll tx,ty;
ll d=exgcd(b,a%b,tx,ty);
x=ty;y=tx-(a/b)*ty;
return d;
}
}
int main()
{
ll a,b,k,x,y;
a = 97;
b = -127;
k = 1;
ll d=exgcd(a,b,x,y);
if(k%d){puts("no solution!");return 0;}
else
{
x=x*k/d;
y=(k-a*x)/b;
}
//printf("%lld %lld\n",x,y);
cout << x + y << '\n';
return 0;
}
凑平方数
分析:
先把0~10000000000内符合标准的平方数找出来,然后用一个长度为10的01串记录状态,这个01串的第i位为1就代表i-1这个数被选了,然后dfs搜索即可。(平方数也用01串的形式表示)
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<ll> v;
int ans;
void check(ll x)
{
ll st = 0;
if(x == 0) st = 1;
while(x)
{
if((st & (1 << (x % 10))) != 0) return ;
st |= (1 << (x % 10));
x /= 10;
}
v.push_back(st);
}
void dfs(int now, ll st)
{
if(st == (1 << 10) - 1)
{
++ans;
return ;
}
for(int i = now; i < v.size(); ++i)
{
if((v[i] & st) == 0) dfs(i + 1, v[i] | st);
}
}
int main()
{
for(ll i = 0; i <= 100000; ++i) check(i * i);
dfs(0, 0);
printf("%d\n", ans);
return 0;
}
机器人塔
分析:
塔中只有两个字母,两个相同的是A,不同的是B,应该想到异或运算,然后A就是0,B就是1。
对于一个塔而言,最下面的一层确定了那么整个塔就确定了,那么我们可以枚举最下面一层的状态,然后判断符不符合。
一. 判断标准自然就是需要0和1的个数
二. 如何由下一层快速的得到上一层:
将这层01串右移一位然后与原来的01串做异或操作,但这样做完还是有点问题的,就是如果当前层是10个字符,那么操作完后有可能上一层得到的那个01串还是10个字符,而实际上该串首字符应该删去
三. 判断一个数变成二进制串后有几个1:
1.将这个数与它-1后取and,判断这个操作进行多少次,进行多少次就有几个1
2. c++ STL bitset的count函数
AC代码:
#include <bits/stdc++.h>
using namespace std;
int n, m, f, ans;
int get_num(int x)
{
bitset<35> bi(x);
return bi.count();
}
bool check(int now, int f)
{
int num0 = 0, num1 = 0;
for(int i = f; i ; --i)
{
int add = get_num(now);
num1 += add;
num0 += (i - add);
now ^= (now >> 1);
now &= (1 << (i - 1)) - 1;
if(num0 > m || num1 > n) return false;
}
return num0 == m && num1 == n;
}
int main()
{
scanf("%d%d", &m, &n);
f = sqrt((m + n) * 2);
for(int i = 0; i < (1 << f); ++i) if(check(i, f)) ++ans;
printf("%d\n", ans);
return 0;
}