一步之遥
从昏迷中醒来,小明发现自己被关在X星球的废矿车里。
矿车停在平直的废弃的轨道上。
他的面前是两个按钮,分别写着“F”和“B”。
小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。
按F,会前进97米。按B会后退127米。
透过昏暗的灯光,小明看到自己前方1米远正好有个监控探头。
他必须设法使得矿车正好停在摄像头的下方,才有机会争取同伴的援助。
或许,通过多次操作F和B可以办到。
矿车上的动力已经不太足,黄色的警示灯在默默闪烁...
每次进行 F 或 B 操作都会消耗一定的能量。
小明飞快地计算,至少要多少次操作,才能把矿车准确地停在前方1米远的地方。
请填写为了达成目标,最少需要操作的次数。
注意,需要提交的是一个整数,不要填写任何无关内容(比如:解释说明等)
答案是97
我是算的,eee 就是假设是97x-127y = 1
那么就一定有 97(y+z) - 127y = 1 ------->
-30y+97z = 1 这样子就很好算出来 z = 13 y = 42 42+55 = 97
凑平方数
把0~9这10个数字,分成多个组,每个组恰好是一个平方数,这是能够办到的。
比如:0, 36, 5948721
再比如:
1098524736
1, 25, 6390784
0, 4, 289, 15376
等等...
注意,0可以作为独立的数字,但不能作为多位数字的开始。
分组时,必须用完所有的数字,不能重复,不能遗漏。
如果不计较小组内数据的先后顺序,请问有多少种不同的分组方案?
注意:需要提交的是一个整数,不要填写多余内容。
此代码有误 我的答案是295不知道要怎么改
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[10],sq[700],now = 0;
ll vis[700],d[10],yy = 0,ans[700];
set<string>st;
string gg[700];
void init()
{
sq[++now] = 0;
for(ll i = 1;i<=99999;i++)
{
ll jj = i*i;ll kk = jj;
memset(a,0,sizeof(a));
while(jj !=0)
{
a[jj%10]++;
jj= jj / 10;
}
ll j ;
for(j = 0;j<10;j++)
{
if(a[j] > 1)
break;
}
if(j==10) sq[++now] = kk;
}
gg[1] = "0";
ans[1] = 1;
for(ll i = 2;i<=now;i++)
{
ll kk = sq[i];
while(kk!=0)
{
gg[i]+=(kk%10+'0');
kk = kk / 10;
}
reverse(gg[i].begin(),gg[i].end());
ans[i] = gg[i].length();
}
}
void DFS(ll k,ll len,ll cnt)
{
if(len>=10)
{
if(len==10)
{
d[++cnt] = k;
sort(d+1,d+1+cnt);//从小到大排序
string s="";
for(int i =1;i<=cnt;i++)
s+=gg[d[i]];
int a[10] = {0};
for(int i =0;i<10;i++)
{
a[s.at(i)-'0']++;
}
int flag = 0;
for(int i =0;i<=9;i++)
{
if(a[i]!=1)
{
flag = 1;
break;
}
}
if(flag==0) {
st.insert(s);
cout<<s<<endl;
}
}
return ;
}
else
{
d[++cnt] = k;
for(ll i = k;i<=now;i++)
{
if(10-len < ans[i])break;
if(vis[i] == 0)
{
vis[i] = 1;
DFS(i,len+ans[i],cnt);
vis[i] = 0;
}
}
}
return ;
}
int main()
{
init();
freopen("C:\\Users\\DELL\\Desktop\\a.txt","w",stdout);
for(ll i = 1;i<=now;i++)
{
printf("%lld %lld %lld ",i,sq[i],ans[i]);
cout<<gg[i]<<endl;
}
for(ll i = 1;i <= now;i++)
{
memset(vis,0,sizeof(vis));
vis[i] = 1;
DFS(i,ans[i],0);
}
cout<<st.size()<<endl;
return 0;
}
来自网上正确的代码:
#include<bits/stdc++.h>
using namespace std;
using namespace std;
long long shu[20];
int ai[10]={0,1,2,3,4,5,6,7,8,9};
set<string> jj;
void dfs(int cur,int num)
{
if(cur==10)
{
long long shu2[20];
for(int i=0;i<num;i++)
shu2[i]=shu[i];
sort(shu2,shu2+num);
string xu;
for(int i=0;i<num;i++)
{
while(shu2[i])
{
int a=shu2[i]%10;
shu2[i]=shu2[i]/10;
char b=a+'0';
xu=xu+b;
}
xu+='-';
}
jj.insert(xu);
return ;
}
if(ai[cur]==0)
{
shu[num]=0;
dfs(cur+1,num+1);
}
else
{
long long sum=0;
for(int i=cur;i<10;i++)
{
sum=sum*10+ai[i];
double son=sqrt(sum);
if(son==(int)son)
{
shu[num]=sum;
dfs(i+1,num+1);
}
}
}
}
int main()
{
do
{
memset(shu,0,sizeof(shu));
dfs(0,0);
}while(next_permutation(ai,ai+10));
cout<<jj.size()<<endl;
return 0;
}
棋子换位
有n个棋子A,n个棋子B,在棋盘上排成一行。
它们中间隔着一个空位,用“.”表示,比如:
AAA.BBB
现在需要所有的A棋子和B棋子交换位置。
移动棋子的规则是:
1. A棋子只能往右边移动,B棋子只能往左边移动。
2. 每个棋子可以移动到相邻的空位。
3. 每个棋子可以跳过相异的一个棋子落入空位(A跳过B或者B跳过A)。
AAA.BBB 可以走法:
移动A ==> AA.ABBB
移动B ==> AAAB.BB
跳走的例子:
AA.ABBB ==> AABA.BB
以下的程序完成了AB换位的功能,请仔细阅读分析源码,填写划线部分缺失的内容。
#include <stdio.h>
#include <string.h>
void move(char* data, int from, int to)
{
data[to] = data[from];
data[from] = '.';
}
int valid(char* data, int k)
{
if(k<0 || k>=strlen(data)) return 0;
return 1;
}
void f(char* data)
{
int i;
int tag;
int dd = 0; // 移动方向
while(1){
tag = 0;
for(i=0; i<strlen(data); i++){
if(data[i]=='.') continue;
if(data[i]=='A') dd = 1;
if(data[i]=='B') dd = -1;
if(valid(data, i+dd) && valid(data,i+dd+dd)
&& data[i+dd]!=data[i] && data[i+dd+dd]=='.'){
//如果能跳...
move(data, i, i+dd+dd);
printf("%s\n", data);
tag = 1;
break;
}
}
if(tag) continue;
for(i=0; i<strlen(data); i++){
if(data[i]=='.') continue;
if(data[i]=='A') dd = 1;
if(data[i]=='B') dd = -1;
if(valid(data, i+dd) && data[i+dd]=='.'){
// 如果能移动...
if( ______________________ ) continue; //填空位置
move(data, i, i+dd);
printf("%s\n", data);
tag = 1;
break;
}
}
if(tag==0) break;
}
}
int main()
{
char data[] = "AAA.BBB";
f(data);
return 0;
}
注意:只提交划线部分缺少的代码,不要复制已有代码或填写任何多余内容。
valid(data, i-dd) && data[i-dd]!=data[i]&&i+dd!=data.length-1&&data[i+dd+dd]==data[i-dd]
意思是 当没有可以跳的 该棋子可移动之前 判断它旁边字母是否与他相同 若相同则移动 若不同 则说明这是刚刚跳过来的 在判断“ . ”后面可还有字母 若有判断与该棋子旁边的旗子是否相同 若相同则说明不该这一旗子移动 continue 过去。
机器人塔
X星球的机器人表演拉拉队有两种服装,A和B。
他们这次表演的是搭机器人塔。
类似:
A
BB
ABA
AABB
BBBAB
ABABBA
队内的组塔规则是:
A 只能站在 AA 或 BB 的肩上。
B 只能站在 AB 或 BA 的肩上。
你的任务是帮助拉拉队计算一下,在给定A与B的人数时,可以组成多少种花样的塔。
输入一行两个整数 M 和 N,空格分开(0<M,N<500),分别表示A、B的人数,保证人数合理性。
要求输出一个整数,表示可以产生的花样种数。
例如:
用户输入:
1 2
程序应该输出:
3
再例如:
用户输入:
3 3
程序应该输出:
4
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
我自己的代码应该会超时吧?我也不知道不过是对的
#include<bits/stdc++.h>
using namespace std;
int book[50][50];
struct node
{
int x,y;
}s[1000];
int n,m,cnt = 1;
bool check(int a,int b)//表示的是a的个数,b表示的是b的个数仅此而已
{
for(int i = cnt;i>=2;i--)
{
if(a>n||b>m)return false;
for(int j =1;j<=i-1;j++)
{
if(book[i][j] == book[i][j+1]) book[i-1][j]=1,a++;
else book[i-1][j] = 2,b++;
}
}
if(a==n&&b==m) return true;
return false;
}
int main()
{
scanf("%d%d",&n,&m);
while(cnt*(cnt+1)/2 != (n+m))
cnt++;
int now = 0;
int gg = min(n,cnt);
for(int i = 0;i<=gg;i++)
{
int kk = cnt - i;
if(m<kk)continue;
if(book[i][kk]==1)continue;
book[i][kk] = 1;
s[++now].x = i;
s[now].y = kk;
}
gg = min(m,cnt);
for(int i = 0;i<=gg;i++)
{
int kk = cnt - i;//这个表示的是A
if(n<kk)continue;
if(book[kk][i]==1)continue;
book[kk][i] = 1;
s[++now].x = kk;//这个表示的是A
s[now].y = i;//这个表示的是B
}
// 1表示A 2表示B
int ans = 0;
memset(book,0,sizeof(book));
for(int i = 1;i <= now;i++)
{
for(int j = 1;j<=s[i].x;j++)
book[cnt][j] = 1;
for(int j = s[i].x+1; j<=cnt;j++)
book[cnt][j] = 2;
do{
if(check(s[i].x,s[i].y))ans++;
} while(next_permutation(book[cnt]+1,book[cnt]+cnt+1));
}
cout<<ans<<endl;
/*
底层全排列 cnt 表示这个可以是多少个
那么全排列就可以从 A从0~~~~n B也可以从0~~m
为了避免重复可以用map稍微弄下 ok就是这个这样子或者是50*50的数组
*/
return 0;
}