B - Catch That Cow
题目如下
那么题意呢,很直观。给俩数n k,在横坐标中,n表示人的位置,k表示牛的位置。人有两类行动方式(行动一次花费一分钟),一种前进1或后退1,一种直接位置*2,而牛不会动,人刚好到牛的位置就结束,求最小时间。
按部就班bfs写就完了。
创建一个队列,一个数存位置,一个数存行动次数。
单组输入n k,如果n>=k,证明人在牛之前,人只需要后退n-k个位置,也就是n-k分钟,就直接输出了。如果不是,那就添加到队列去处理。
如果队列中有数据,就取出来。判断是否等于k,满足则代表人到牛的位置了,输出行动次数。不满足则开始行动。
在行动中,会发现一个问题,比如从5到10,可以用第一类行动,前进5次,花费5分钟,也可以用第二类,花费1分钟。那么怎么选择最短的呢?
那么就需要开一个bool型的数组来记录是否已经到过这个位置了。如果在进行行动时,发现下一步到的位置是已经记录了到过的,就停止这步行动那么,如果判断没有到过这个位置,就可以建立分支。从起始点,可以有三个分支,而第二步行动时每个分支又有三个分支,依次形成一个“树”。按照题意0 ≤ n,k≤ 100,000,也就是建分支直到位置到100000(当然实际上,当人到牛的位置时就停止不建了)
别忘了:1.到过一个位置后标记已经到过了。2.当你在下一步行动之前,把队列中上一步的位置信息删除掉,否则就一直循环下去了。
那么最后的代码奉上
#include#include using namespace std; int n,k; bool visit[100005]; struct node { int x; int ans; }; int bfs() { queue q; q.push({n,0}); while(q.size()) { node now=q.front(); if(now.x==k) return now.ans; else if(!visit[now.x]) { visit[now.x]=1; if(now.x+1<=100000) q.push({now.x+1,now.ans+1}); if(now.x-1>=0) q.push({now.x-1,now.ans+1}); if(now.x*2<=100000) q.push({now.x*2,now.ans+1}); } q.pop(); } return 0; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin>>n>>k; if(n>=k) cout< endl; else cout< endl; return 0; }
C - Find The Multiple
题目如下
这道题也比较一般,根据题意。多组数,求每个数的只含有0 1的最小公倍数。
输入的数>>需输出的数>>输出的数拆解后
1>>1>>1
2>>10>> 1*10
3>>111>> (1*10+1)*10+1
4>>100>> 1*10*10
5>>10>> 1*10
6>>1110>> ((1*10+1)*10+1)
······
可以看出,其实这是有规律的,那么可以从x=1开始,判断x*10%n或(x*10+1)%n是否为0,然后同样的,如果这步操作没有满足条件的,这两个分支再来开分支。
需要注意的是:1.数据大。2.每步操作完了删除队列中的这个数据,理由同上题。
完整代码
#include#include using namespace std; int n; queue <long long int> q; long long int bfs() { while(q.size()) { q.pop(); } q.push(1); while(q.size()) { if(q.front()%n==0) { return q.front(); } long long int temp=q.front(); q.pop(); q.push(temp*10); q.push(temp*10+1); } return 0; } int main() { while(cin>>n&&n) { cout< endl; } return 0; }
E - Oil Deposits
题目↓↓↓↓↓↓↓↓↓↓
这道题是多组数据。每组第一行给两个数,分别代表行数和列数,接下来有一个图,“*”为土,“@”为油田。规定一块油田可以上下左右斜着连在一起,找图里共有几块油田。
bcehj