A - Modular Exponentiation
思路:如果n>31,输出m;m<=31,直接取模
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(void)
{
ll n,m,ans=1;
cin >>n >>m;
if(n>32) cout << m <<endl;
else
{
for(int i=1;i<=n;i++)
ans*=2;
cout << m%ans << endl;
}
}
B - Christmas Spruce
思路:模拟
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<int> vec[1005];
int main(void)
{
int n;
cin >>n;
for(int i=2;i<=n;i++)
{
int p;
scanf("%d",&p);
vec[p].push_back(i);
}
bool flag=true;
for(int i=1;i<=n;i++)
{
int cntleaf=0;
if(vec[i].size()!=0)
{
for(int j=0;j<vec[i].size();j++)
{
if(vec[vec[i][j]].size()==0) cntleaf++;
}
if(cntleaf<3)
{
flag=false;
break;
}
}
}
if(flag) cout <<"Yes"<<endl;
else cout<<"No"<<endl;
}
C - Party Lemonade
思路:二分最小值。check当前的money是不是能够购买L升以上的饮料
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=30+5;
ll cost[MAX_N];
ll n,l;
bool check(ll money)
{
//cout <<"money="<<money << endl;
ll liter=0;
for(int i=n;i>=1;i--)
{
if(money>=cost[i])
{
ll p=money/cost[i];
if(p>=l) return true; //限制p的范围小于l,否则会爆LL
liter+=p*(1<<(i-1));
//cout <<" p="<<p<<" i="<<i<<" liter="<<liter<<endl;
money-=p*cost[i];
}
}
//cout << endl;
return liter >=l ;
}
int main(void)
{
cin >>n >>l;
for(int i=1;i<=n;i++)
cin >> cost[i];
for(int i=2;i<=n;i++)
cost[i]=min(cost[i],cost[i-1]*2);//cost[i]为1~i中,相同 体积2^(i-1) 价格最低的饮料
ll l=1,r=1e18,mid;
ll ans;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout << ans << endl;
}
D:Too Easy Problems
思路:二分最大值。check假设得到X分,判断是不是满足该情况。如果当前得x分,而实际上>=x,x可变大。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX_N=2e5+50;
int n,t;
vector <int> aaa;
struct node
{
int a,t,id;
}p[MAX_N];
bool cmp(node a,node b)
{
return a.t<b.t;
}
bool check(int x)
{
aaa.clear();
int cnt=0;
int tottime=0;
//cout <<"x=" <<x <<endl;
for(int i=1;i<=n;i++)
{
if(tottime+p[i].t<=t && p[i].a>=x)
{
aaa.push_back(p[i].id);
// cout <<"id="<<p[i].id<<endl;
tottime+=p[i].t;
cnt++;
}
}
return cnt>=x;
}
int main(void)
{
cin >>n >>t;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].a,&p[i].t);
p[i].id=i;
}
sort(p+1,p+1+n,cmp);
/*for(int i=1;i<=n;i++)
{
printf("%d %d %d\n",p[i].a,p[i].t,p[i].id);
}*/
int l=0,r=n,mid;
int ans;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
//printf("check(%d)=%d\n",mid,check(mid));
}
cout << ans << endl << ans << endl;
check(ans); //注意再check一次,使得aaa中的元素是答案,而不是其他值check的值。
for(int i=0;i<ans;i++) cout <<aaa[i]<<" ";
cout << endl;
}
总结:最值问题,考虑二分+贪心。 即对特定的解是否满足题目的约束条件[贪心]