a+b
由于sqrt函数求平方根在求大数的时候会有精度问题,可以用二分或者将函数求出的结果判断一下,才能获得正确答案。
#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int N=2e5+10,INF=0x3f3f3f3f,mod=998244353;
void solve()
{
int a,b; cin>>a>>b;
int m=1e12;
int s=a*m+b*m-1;
int ans=sqrt(s);
if(ans*ans>s) ans--;
cout<<ans<<"\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t=1; cin>>t;
while(t--)
{
solve();
}
return 0;
}
借椅子Ⅰ
贪心
#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int N=2e5+10,INF=0x3f3f3f3f3f3f3f3f,mod=998244353;
PII p[N];//存放每个实验室的距离和椅子数量
int v[N];//存放取完之后只剩一个椅子的实验室的距离
void solve()
{
int n,m,k; cin>>n>>m>>k;
int s=0;//去别的实验室总共可以获得的椅子数量
for(int i=1;i<=n;i++)
{
int a,b; cin>>a>>b;
//b放在前面,因为后面对p数组排序是根据第一个关键字排序的
p[i]={b,a};
s+=a;
}
//如果所有的椅子加起来都不够,输出-1
if(s+m<k)
{
cout<<"-1\n"; return ;
}
int sum=k-m;//存还需要多少椅子
//如果不缺椅子,输出0
if(sum<=0)
{
cout<<"0\n"; return ;
}
sort(p+1,p+1+n);
int l=0,r=0;
int ans=0;//存答案
for(int i=1;i<=n;i++)
{
int d=p[i].x,cnt=p[i].y;//d表示这个实验室的距离,cnt表示这个实验室具有的椅子数量
//如果前面用完但是还剩一个椅子的实验室大于两个,就要判断
//前面两个实验室分别单独取更优,还是在当前实验室取两个椅子更优
while(r-l>=2 and v[l]+v[l+1]<=d)
{
ans+=v[l]+v[l+1];
l+=2;
sum-=2;
}
//看当前实验室的椅子需要多少个两次才能取完 ,并且不超过需要的椅子
int t=min(sum/2,cnt/2);
ans+=t*d;
sum-=t*2;
cnt-=t*2;
if(!sum) break;
//如果最后该实验室还剩一个椅子,那么就加到v里面
if(cnt)
{
v[r++]=d;
}
}
//如果最后还缺一个椅子,那么从v头去一个就行,因为我们先放进去的是距离最短的
if(sum) ans+=v[l];
//来回所以乘以2
cout<<ans*2<<"\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t=1; //cin>>t;
while(t--)
{
solve();
}
return 0;
}
借椅子Ⅱ
dp
#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int N=2e5+10,INF=0x3f3f3f3f3f3f3f3f,mod=998244353;
PII p[N];//存放每个实验室的距离和椅子数量
int dp[1010][2222];//dp[i][j]表示在前i个实验室中取,椅子总和大于等于j所需要的最短距离
void solve()
{
int n,m,k; cin>>n>>m>>k;
int s=0;//去别的实验室总共可以获得的椅子数量
for(int i=1;i<=n;i++)
{
int a,b; cin>>a>>b;
//b放在前面,因为后面对p数组排序是根据第一个关键字排序的
p[i]={b,a};
s+=a;
}
//如果所有的椅子加起来都不够,输出-1
if(s+m<k)
{
cout<<"-1\n"; return ;
}
int sum=k-m;//存还需要多少椅子
//如果不缺椅子,输出0
if(sum<=0)
{
cout<<"0\n"; return ;
}
//初始化
memset(dp,0x3f,sizeof dp);
for(int i=0;i<=m;i++) dp[0][i]=0;//m个椅子都不需要到别的实验室去借
for(int i=1;i<=n;i++)
{
for(int j=0;j<=k;j++)
{
dp[i][j]=min(dp[i-1][j],dp[i-1][max((int)0,j-p[i].y)]+p[i].x);
}
}
cout<<dp[n][k]*2<<"\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t=1; //cin>>t;
while(t--)
{
solve();
}
return 0;
}
兔子
BFS模板题
代码如下:
#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int N=3333,INF=0x3f3f3f3f3f3f3f3f,mod=998244353;
int n,m,k;
int g[N][N];//存桌子每一处的高度
int stx,sty;//起始位置
int d[N][N];//记录到这一点的最短距离
//8个方向
int dir[8][2]={{0,1},{1,0},{-1,0},{0,-1},{-1,-1},{-1,1},{1,-1},{1,1}};
void solve()
{
cin>>n>>m>>k; cin>>stx>>sty;
for(int i=1;i<=n+2;i++)
{
for(int j=1;j<=m+2;j++) cin>>g[i][j];
}
//为了方便判断,这里从起始位置到起始位置的距离置为1,
//这样d[x][y]==0表示这个点还没记录
d[stx][sty]=1;
//BFS
queue<PII> q;
q.push({stx,sty});
while(q.size())
{
auto t=q.front(); q.pop();
//枚举8个方向
for(int i=0;i<8;i++)
{
//求出每个方向新的x,y
int x=t.x+dir[i][0],y=t.y+dir[i][1];
//如果这个点之前算过,那么他的最短距离已经知道了
//或者两点的距离超过k,那么兔子跳不到这个点
if(d[x][y] || abs(g[t.x][t.y]-g[x][y])>k) continue;
//如果它到达边界了,那么一定是最短的答案
if(x==1||x==n+2||y==1||y==m+2)
{
cout<<d[t.x][t.y]; return;
}
d[x][y]=d[t.x][t.y]+1;
q.push({x,y});
}
}
//上面每个点都遍历了但是没有答案,那么不能到达输出-1
cout<<"-1\n";
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t=1; //cin>>t;
while(t--)
{
solve();
}
return 0;
}
最长的&
位运算
#include<bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef pair<int,int> PII;
typedef unsigned long long ull;
const int N=2e5+10,INF=0x3f3f3f3f3f3f3f3f,mod=998244353;
int mp[50];//存放二进制位置i为1的数的个数
int a[N];
void solve()
{
int n; cin>>n;
memset(mp,0,sizeof mp);
int ans=0;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
int xx=a[i];
for(int j=0;j<=32;j++)
{
if((xx>>j)&1) mp[j]++;ans=max(ans,mp[j]);
}
}
cout<<ans<<"\n";
}
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
int t=1; //cin>>t;
while(t--)
{
solve();
}
return 0;
}