【ABC 301】D 思维
D
这道题被卡了很久。。。惭愧。。。
题意
给你一个由组成的字符串和一个数(),你可以把一个 变成 0 或者 1,问最大能表示的不超过的数是多少。
正解
先判断 -1 的情况:S能表示的最小的数是所有❓都填0所表示的数字,如果这个数都大于,肯定是无解的,否则有解
策略:如果某一位❓填1仍然,就填1,否则填0
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10;
string s, t;
ll n, ans;
int main() {
cin >> s >> n;
int len = s.length();
for(int i = 0; i < len; i++) {
if(s[i] == '1') ans |= (1ll << (len - 1 - i));
}
if(ans > n) {
puts("-1");
return 0;
}
for(int i = 0; i < len; i++) {
if(s[i] == '?') {
if((ans | (1ll << (len - 1 - i))) <= n) ans |= (1ll << (len - 1 - i));
}
}
printf("%lld\n", ans);
return 0;
}
我的错解
我的思路不是比较数值大小,是比较字符串(没过脑。。。。)
错的点在于考虑漏了一种情况(悲,修改后即可ac
debug超久总算ac的shishan代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10;
string s, t;
ll n;
int main() {
cin >> s >> n;
int len = s.length(); // 2 ^ [len - 1, ... ,0]
// n转字符串
for(int i = 0; i <= 60; i++) {
if((n & (1ll << i)) != 0) t.push_back('1'), n -= (1ll << i);
else t.push_back('0');
if(!n) break;
}
reverse(t.begin(), t.end());
// cout << "t : " << t << endl; ///
// t更长 直接输出
if(t.length() > len) {
ll ans = 0;
for(int i = 0; i < len; i++) {
if(s[i] != '0') ans = ans * 2 + 1;
else ans *= 2;
}
cout << ans << endl;
return 0;
}
// t短 补全
if(t.length() < len) {
int times = len - t.length();
for(int i = 1; i <= times; i++) t = "0" + t;
// cout << "t : " << t << endl; ///
}
// 找 最初的上1下0 并看是否能补救 !!!!!!WA的原因:10之前可能已经有01了,修改后即可ac
int flag = -1;
bool occur = 0;
for(int i = 0; i < len; i++) {
if(s[i] == '1' && t[i] == '0' && !occur) {
flag = i;
break;
}
if(s[i] == '0' && t[i] == '1') {
occur = 1;
break;
}
}
if(flag != -1) {
bool ok = 0;
for(int i = flag - 1; i >= 0; i--) {
if(t[i] == '1' && (s[i] == '0' || s[i] == '?')) {
ok = 1;
s[i] = '0';
break;
}
}
if(!ok) {
puts("-1");
return 0;
}
}
// 照搬 or 可以全1
bool f = 0;
for(int i = 0; i < len; i++) {
if(s[i] == '?') {
if(!f) s[i] = t[i];
else s[i] = '1';
}
else {
if(s[i] == '0') {
if(!f && t[i] == '1') f = 1;
}
}
}
ll ans = 0;
for(int i = 0; i < len; i++) {
if(s[i] == '1') ans = ans * 2 + 1;
else ans *= 2;
}
cout << ans << endl;
return 0;
}
总结
这次的D题让我想到了以前的很多时刻。
我总是这样,常常出现在写模拟题的时候,在思路还不明晰的时候匆忙开始,然后一直一直debug,最后还不保证能解决问题。
我把它总结为因为一时的懒惰而要花费巨大的代价(比如这次还用Mac对拍了,虽说这也是必备技能)去弥补。
得 不 偿 失 。
以后再遇到类似的情况,我一定要先在纸上写下清晰的过程,再开始做。
谢谢trq让我意识到这个问题,看来我还有很大的上升空间呀(
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】