【CodeForces - 520B】Two Buttons (bfs或dp或时光倒流,trick)
題干:
Vasya has found a strange device. On the front panel of a device there are: a red button, a blue button and a display showing some positive integer. After clicking the red button, device multiplies the displayed number by two. After clicking the blue button, device subtracts one from the number on the display. If at some point the number stops being positive, the device breaks down. The display can show arbitrarily large numbers. Initially, the display shows number?n.
Bob wants to get number?m?on the display. What minimum number of clicks he has to make in order to achieve this result?
Input
The first and the only line of the input contains two distinct integers?n?and?m?(1?≤?n,?m?≤?104), separated by a space .
Output
Print a single number — the minimum number of times one needs to push the button required to get the number?m?out of number?n.
Examples
Input
4 6Output
2Input
10 1Output
9Note
In the first example you need to push the blue button once, and then push the red button once.
In the second example, doubling the number is unnecessary, so we need to push the blue button nine times.
?
解題報告:
? ?這題做法很多。。首先一眼就是老套的bfs,,就不說了。。。注意別忘判斷出現(xiàn)小于0的情況就行了,,不然會RE的。。也就是你給他限制了上界別忘了限制下界就行了。(復雜度on的)
? ?還有一種方法就是倒著考慮這個問題,這個問題可以反過來說:我們應該用“對這個數(shù)加1”和“如果這個數(shù)是偶數(shù),就除以2”的運算,得到從m開始的n。(復雜度logn的)
? ?因為你要知道啊如果m是個奇數(shù),也就意味著我最終一定是先得到一個偶數(shù)然后再-1得到的,所以我們就加回去成個偶數(shù),然后偶數(shù)要想得到n,毫無疑問只能/2,然后如果發(fā)現(xiàn)<n了,那就直接加回來就是答案了。這倒是不難想,因為你會發(fā)現(xiàn) ÷2+1+1和+1÷2,得到的效果相同,但是后者僅用了兩步,,所以說明這樣貪心一定是時間最短的(相當于推出了bfs的策略,就可以不用bfs直接遞推就可以了)。
? 另外這個解法可以化簡成dp的形式
AC代碼1:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; char s[MAX]; int vis[50005]; int n,m; ll mod = 1e9+7; struct Node {int x;int t;Node(int x,int t):x(x),t(t){} }; int bfs() {queue<Node> q;q.push(Node(n,0));while(!q.empty()) {Node cur = q.front();q.pop();if(cur.x == m) return cur.t;if(vis[cur.x]) continue;if(cur.x < 0) continue;if(cur.x > 50005) {printf("hahahhaha\n");}vis[cur.x]=1;q.push(Node(cur.x-1,cur.t+1));if(cur.x <= m) q.push(Node(cur.x*2,cur.t+1));}return -1; } int main() {cin>>n>>m;if(n>=m) printf("%d\n",n-m);else {int ans = bfs();printf("%d\n",ans);}return 0 ;}AC代碼2:(思維)
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; int main() {int n,m;cin>>n>>m;if(n>=m) printf("%d\n",n-m);else {int ans = 0; //這樣正著推是錯的、、、。。。。 // while(n*2<=m) { // n*=2;ans++; // } // if(m%2 == 0) { // printf("%d\n",ans+((n-m/2)+1)); // } // else printf("%d\n",ans+1+n-m);while(n!=m) {if(m%2==1) ans++,m++;m/=2;ans++;if(n>=m) {ans+=(n-m);break;}}printf("%d",ans);}return 0 ;}?
AC代碼3:(會慢一點,100ms左右)
#include <bits/stdc++.h> using namespace std;int n, m, dp[2][20000], curr, last, cnt;int main() {scanf("%d %d", &n, &m);if(m < n){printf("%d\n", n-m);return 0;}dp[0][m] = 1;last = 0;curr = 1;while(cnt<10000){for(int i = 0; i<2*m; i++) {if(dp[last][i]){if(i == n){printf("%d\n",cnt);return 0;}if( i+1 < 20000 ) dp[curr][i+1] = true;if( i%2 == 0 ) dp[curr][i/2] = true;}}curr=!curr;last=!last;cnt++;}return 0; }AC代碼4:
總結(jié)
以上是生活随笔為你收集整理的【CodeForces - 520B】Two Buttons (bfs或dp或时光倒流,trick)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多家平台的互联网存款被下架,发生了什么?
- 下一篇: 【牛客 - 368D】动态连通块(并查集