0x3f3f3f3f:理想的无穷大数

本文探讨了在32位整数中如何合理地表示无穷大,提出0x3f3f3f3f相较于0x7fffffff的优势:既能避免数据溢出又能通过memset快速初始化数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多时候,我们都取0x7fffffff作为无穷大的代表,因为这是32-bit int的最大值。但是在更多的情况下,0x7fffffff并不是一个好的选择,它并不能满足“无穷大加一个有穷的数依然是无穷大”,它变成了一个很小的负数。除了要满足加上一个常数依然是无穷大之外,我们的常量还应该满足“无穷大加无穷大依然是无穷大”,这一点上0x7fffffff依然不能满足我们。另外它并不是真正意义上的无穷大数,也就是说,只要找到一个极大的数来代替它就行了。
而0x3f3f3f3f就很好的满足了这样的条件。
(1)0x3f3f3f3f的十进制是1061109567,也就是10^9 级别的(和0x7fffffff一个数量级),意味着它可以作为无穷大使用而不致出现数据大于无穷大的情形。
由于一般的数据都不会大于10^9,所以无穷大加上一个数据时并不会溢出。
(2)0x3f3f3f3f+0x3f3f3f3f<0x7fffffff,所以0x3f3f3f3f能够满足我们“无穷大加无穷大为无穷大”的需求。
(3)如果我们想要将某个数组全体赋值为零,我们可以用

memset(a,0,sizeof(a));

来实现,但当我们想将某个数组全部赋值为0x7fffffff时,就得自己写for循环了,因为memset是按字节操作的,它能够对数组清零是因为0的每个字节都是0,而0x3f3f3f3f的每个字节都是0x3f。所以

memset(a,0x3f,sizeof(a);

多么美妙。

#include<bits/stdc++.h> using namespace std; #define endl &#39;\n&#39; typedef long long ll; ll inf=0x3f3f3f3f3f3f3f3f; ll ll1=1; ll dp[61][61]; void solve(){ ll x,y;cin>>x>>y; ll ans=inf; for(ll i=0;i<=60;i++){ for(ll j=0;j<=60;j++){ ll tx=x>>i; ll ty=y>>j; if(tx==ty){ ans=min(ans,dp[i][j]); } } } cout<<ans<<endl; return; } int main(){ ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); memset(dp,0x3f,sizeof dp);dp[0][0]=0; for(ll k=1;k<=60;k++){ for(ll i=60;i>=0;i--){ for(ll j=60;j>=0;j--){ if(i>=k)dp[i][j]=min(dp[i][j],dp[i-k][j]+(ll1<<k)); if(j>=k)dp[i][j]=min(dp[i][j],dp[i][j-k]+(ll1<<k)); } } } ll _;cin>>_; while(_--)solve(); }#include <iostream> #include <vector> #include <map> #include <algorithm> #include <cstring> #define int long long using namespace std; signed main() { ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); vector<vector<int>> dp(65, vector<int>(65, 0x3f)); dp[0][0] = 0; auto init = [&]() -> void{ for(int k = 1; k <= 60; k ++) { for(int i = 60; i >= 0; i --) { for(int j = 60; j >= 0; j --) { if(i >= k) dp[i][j] = min(dp[i][j], dp[i - k][j] + (long long)(1 << k)); if(j >= k) dp[i][j] = min(dp[i][j], dp[i][j - k] + (long long)(1 << k)); } } } }; int t; cin >> t; init(); while(t --) { int ans = 1e18; int x, y; cin >> x >> y; for(int i = 0; i <= 60; i ++) { for(int j = 0; j <= 60; j ++) { int xx = x >> i; int yy = y >> j; if(xx == yy) { ans = min(ans, dp[i][j]); } } } cout << ans << &#39;\n&#39;; } }为什么第二段代码的结果和第一段代码不一样
最新发布
03-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值