气球条幅 balloon
题解
将气球和条幅都从小到大排序就行,然后一个一个的匹配
Code
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
long long a[maxn],b[maxn];
int main(){
//freopen("balloon.in","r",stdin);
//freopen("balloon.out","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i],&b[i]);
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
long long ans=0,cnt=1;
for(int i=1;i<=n;i++){
if(a[i]>=b[cnt]){
ans++;
cnt++;
}
}
printf("%lld",ans);
return 0;
}
实数集合 real
题解
大于1的正数都要取,负数要选的话就要一次性选两个
Code
#include <bits/stdc++.h>
using namespace std;
int a[10005];//最后答案
bool flag[10005];//标记数组
struct tt{
double a;
int pos;
} t[10005];//存储数组
bool cmp(tt a, tt b){//比较器
return a.a < b.a;//从小到大进行枚举
}
int main(){
int m,cas,n,k;
cin>>cas;
while (cas--){
//初始化
memset(a, 0, sizeof(a));//清空数组
memset(flag, 0, sizeof(flag));
memset(t, 0, sizeof(t));
cin>>n;
for (int i=1;i<=n;i++){
cin>>t[i].a;
t[i].pos=i;//记录编号
}
sort(t+1,t+n+1,cmp);//排序
int cnt = 0;
for (int i=1;i<=n;i++){
if (t[i].a<0)cnt++;//记录负数的个数
}
for (int i=1;i<=cnt;i++){//枚举负数
if (!flag[i]){//如果当前这个点
if (t[i].a * t[i + 1].a > 1 + 1e-6){//判断这两个数相乘是否大于1
//如果成功,则选择
flag[i]=true;
flag[i+1]=true;
}
}
}
for (int i=cnt;i<=n;i++){//如果是正数,则需要大于1才可以选择
if (t[i].a >1+1e-6){
flag[i]=true;
}
}
cnt=0;//清空cnt,为后面存答案做准备
for (int i=1;i<=n;i++){//存储答案
if (flag[i]){
cnt++;
a[cnt]=t[i].pos;
}
}
sort(a+1,a+cnt+1);//按照编号的顺序从小到大进行排序
if (cnt==0){//如果一个都没有选择则进行特判
if (n==1){//如果只有一个数
cout<<1<<endl<<1<< endl;
}
else{
//否则选择最小的两个数和一个最大数
double tmp=t[1].a*t[2].a;
double tmp2=t[n].a;
if (tmp>tmp2+1e-6){//如果两个数的乘积大于一个数
int a=t[1].pos;
int b=t[2].pos;
//按照编号从小到大进行排序
if (a>b)cout<<2<<endl<<b<<" "<<a<<endl;
else cout<<2<<endl<<a<<" "<<b<<endl;
}
else cout<<1<<endl<<t[n].pos<<endl;//如果一个数大于两个数的乘积
}
}else {//如果有选择,则正常输出
cout<<cnt<<endl;
for(int i=1;i<=cnt;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
}
return 0;
}
十六 sixteen
题解
通过记录前缀来判断,并且枚举截断点
Code
#include <bits/stdc++.h>
using namespace std;
#define LL long long
string s;
int p, q;
const int N = 1e7 + 100;
LL l[N], r[N];//记录前缀和后缀
int num(char c){//十六进制转十进制
if (c>='0'&&c<='9')return c-'0';
else return c-'a'+10;
}
int main(){
cin>>s;
cin>>p>>q;
int len=s.length();//记录长度
for (int i=0;i<len;i++){
l[i]=(l[i-1]*16+num(s[i]))%p;//根据取余算法进行前缀和
}
LL tmp=1;//记录当前的幂
for (int i=len-1;i>=0;i--){
r[i]=(r[i+1]+num(s[i])*tmp)%q;//记录后缀
tmp=(tmp*16)%q;//当前指数并取余
}
int cnt=0;//记录答案
for (int i=1;i<len-2;i++){//枚举断点
if (l[i]==0&&r[i+1]==0&&s[i+1]!='0'){//如果条件成立
cnt++;
}
}
if (l[len-2]==0&&r[len-1]==0)cnt++;//特判
cout<<cnt;
return 0;
}
飞翔 flappy
题解
记录能到达的最高点和最低点,如果最高点小于最低点就不行,然后从后往前进行模拟
Code
#include <bits/stdc++.h>
using namespace std;
int n, v;
int up[1000100], down[1000100], maxv[1000100], minv[1000100];//maxv和minv记录最小的上限和最大的下限
int main(){
cin>>n>>v;
for (int i=1; i <= n; i++){
cin>>down[i]>>up[i];
}
maxv[0]=minv[0]=v;//初始条件
for (int i=1;i<=n;i++){
maxv[i]=min(maxv[i-1]+1,up[i]);//比较上一位+1和当前位
minv[i]=max(minv[i-1]-1,down[i]);
if (maxv[i]<minv[i]){//如果上限比下限小
cout<<"impossible"<<endl<<i;//那么就一定不可以
return 0;
}
}
long long sum=maxv[n];//从后往前进行推
for (int i= n-1;i>=1;i--){
if (maxv[i+1]+1<maxv[i])maxv[i]=maxv[i+1]+1;//如果方案明显达不到,就更新
sum+=maxv[i];//加上上边界
}
cout<<sum<<endl;
return 0;
}