一步之遥
从昏迷中醒来,小明发现自己被关在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; }