目录
华华给月月准备礼物【二分】
https://ac.nowcoder.com/acm/problem/23049
就是一个常见的二分模板
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],n,k;
bool check(int x)
{
int cnt=0;
for(int i=0;i<n;i++) cnt+=a[i]/x;
if(cnt>=k) return true;
return false;
}
int main(void)
{
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
LL l=0,r=1e9+10;
while(l<r)
{
LL mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<l;
return 0;
}
The Biggest Water Problem【模拟】
https://ac.nowcoder.com/acm/problem/15173
#include<bits/stdc++.h>
using namespace std;
int main(void)
{
int n; cin>>n;
while(n>=10)
{
int sum=0;
while(n) sum+=n%10,n/=10;
n=sum;
}
cout<<n;
return 0;
}
Bits【递归模拟 / 未完成】
https://ac.nowcoder.com/acm/problem/201605
[NOIP2004]FBI树【树的后序遍历】
https://ac.nowcoder.com/acm/problem/16660
#include<bits/stdc++.h>
using namespace std;
int n;
string s;
void dfs(string s)
{
if(s.size()>1)
{
dfs(s.substr(0,s.size()/2));
dfs(s.substr(s.size()/2));
}
int cnt0=0,cnt1=0;
for(int i=0;i<s.size();i++)
if(s[i]=='0') cnt0++;
else cnt1++;
if(cnt0&&cnt1) cout<<'F';
else if(cnt0&&!cnt1) cout<<'B';
else cout<<'I';
}
int main(void)
{
cin>>n>>s;
dfs(s);
return 0;
}
[USACO 2009 Dec S]Music Notes【二分+前缀和】
https://ac.nowcoder.com/acm/problem/24866
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n,m;
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
while(m--)
{
int x; cin>>x;
int l=1,r=n;
while(l<r)
{
int mid=l+r>>1;
if(a[mid]>=(x+1)) r=mid;
else l=mid+1;
}
cout<<l<<endl;
}
}
[NOIP2009]分数线划定【模拟】
https://ac.nowcoder.com/acm/problem/16625
#include<cstdio>
#include<algorithm>
using namespace std;
struct student
{
int sum;//分数
int id;//学号
}s[5005];
bool cmp(student a,student b)
{
if(a.sum!=b.sum)
return a.sum>b.sum;
else
return a.id<b.id;
}
int main(void)
{
int n,m;//n代表总的人数 m代表志愿者人数
int end_number;//进入面试的人数
int end_score;//面试分数线
int i;
scanf("%d %d",&n,&m);
end_number=m*1.5;
for(i=0;i<n;i++)
{
scanf("%d %d",&s[i].id,&s[i].sum);
}
sort(s,s+n,cmp);//总的排序
end_score=s[end_number-1].sum;//面试的分数线
for(i=end_number;i<n;i++)//加上重分的人
{
if(s[i].sum==end_score)
end_number++;
else
break;
}
printf("%d %d\n",end_score,end_number);
for(i=0;i<end_number;i++)
{
printf("%d %d\n",s[i].id,s[i].sum);
}
return 0;
}
逆序数【归并排序】
https://ac.nowcoder.com/acm/problem/15163
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],b[N],n,res;
void merge_sort(int l,int r)
{
if(l>=r) return;
int i=l,mid=l+r>>1,j=mid+1;
merge_sort(l,mid),merge_sort(mid+1,r);
int k=0;
while(i<=mid&&j<=r)
{
if(a[i]<=a[j]) b[k++]=a[i++];
else
{
res+=mid-i+1;
b[k++]=a[j++];
}
}
while(i<=mid) b[k++]=a[i++];
while(j<=r) b[k++]=a[j++];
for(int i=l,j=0;i<=r;i++,j++) a[i]=b[j];
}
int main(void)
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
merge_sort(0,n-1);
cout<<res;
return 0;
}
逆序对【组合数 / 推式子】
https://ac.nowcoder.com/acm/problem/14731
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int mod=1e9+7;
LL quick_mi(LL a,LL b, LL p)
{
LL sum=1;
while(b)
{
if(b&1) sum=sum*a%p;
b>>=1;
a=(a*a)%p;
}
return sum%p;
}
int main(void)
{
LL n; cin>>n;
if(n==1) cout<<0;
else if(n==2) cout<<1;
else cout<<(n%mod)*((n-1)%mod)%mod*quick_mi(2,n-3,mod)%mod;
return 0;
}
完全平方数【二分】
https://ac.nowcoder.com/acm/problem/14733
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
vector<LL>ve;
int main(void)
{
for(LL i=0;i<=1e5;i++) ve.push_back(i*i);
int n; cin>>n;
while(n--)
{
LL a,b,l,r; cin>>a>>b;
int len1=0,len2=0;
l=0,r=ve.size()-1;
while(l<r)
{
int mid=l+r>>1;
if(ve[mid]>=a) r=mid;
else l=mid+1;
}
len1=l;
l=0,r=ve.size()-1;
while(l<r)
{
int mid=l+r+1>>1;
if(ve[mid]<=b) l=mid;
else r=mid-1;
}
len2=l;
cout<<len2-len1+1<<endl;
}
return 0;
}
[USACO 2010 Feb S]Chocolate Eating【二分】
https://ac.nowcoder.com/acm/problem/24724
注意的一点是: 开一个备用数组 只有满足条件时再保存答案 避免数组错乱保存
还需注意的是,当我们满足时,如果巧克力吃的天数不够,那么统一的最后一天吃。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef unsigned long long int LL;
LL a[N],s,n,m;
LL ans[N];
bool check(LL mid)
{
LL len=1,temp=0;
LL backup[N]={
0};
for(int i=1,j=1;i<=m;i++)//枚举天数
{
while(temp<mid&&j<=n) temp+=a[j],backup[j]=i,j++;
if(temp<mid) return false;//不满足
temp/=2;
}
memcpy(ans,backup,sizeof ans);
return true;
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i],s+=a[i];
LL l=0,r=s;
while(l<r)
{
LL mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
cout<<l<<endl;
for(int i=1;i<=n;i++)
{
if(!ans[i]) ans[i]=m;//天数不够
cout<<ans[i]<<endl;
}
return 0;
}
第k小数【快排】
https://ac.nowcoder.com/acm/problem/207028
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
int a[N],t,n,k;
inline int read(){
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if (ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = (x<<1) + (x<<3) + (ch^48);
ch = getchar();
}
return x * f;
}
int main(void)
{
t=read();;
while(t--)
{
n=read(); k=read();
for(int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+n+1);
printf("%d\n",a[k]);
}
return 0;
}