gym 101911
Posted -citywall123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gym 101911相关的知识,希望对你有一定的参考价值。
A. Coffee Break
题意:每天有m小时,你喝咖啡需要花一小时,你想在n个时刻都喝过一次咖啡,老板规定连续喝咖啡的间隔必须是d以上,求最少需要多少天才能喝够n次咖啡,并输出每个时刻第几天喝。
题解:map+优先队列,用map将愿意喝咖啡的时间喝在第几天喝咖啡映射起来,优先队列遍历每个时刻和上一次喝的时间间隔是否大于d,若大于d,表示可以同一天喝,否则就在下一天喝
#include<iostream> #include<algorithm> #include<math.h> #include<string> #include<string.h> #include<vector> #include<utility> #include<map> #include<queue> using namespace std; map<int,int>m; priority_queue<int,vector<int>,greater<int> >p; int a[200005],b[200005]; int main() int n,t,d; scanf("%d%d%d",&n,&t,&d); for(int i=0;i<n;i++) scanf("%d",&b[i]); a[i]=b[i]; sort(a,a+n); m[a[0]]=1;//最小的时间点一定是第一天就可以喝 p.push(a[0]); int cnt=1; for(int i=1;i<n;i++) int now=p.top(); if(a[i]-now>d) m[a[i]]=m[now];//可以同一天喝 p.pop(); else m[a[i]]=++cnt;//只能下一天喝 p.push(a[i]); printf("%d\n",cnt); for(int i=0;i<n;i++) if(i==0) printf("%d",m[b[i]]); else printf(" %d",m[b[i]]); printf("\n"); return 0;
B
C. Bacteria
题意:碗里有n个细菌,只有重量相同的细菌才可以合并在一起,合并后的细菌为两个细菌之后,为了把碗里的所有细菌合并成一个细菌,问最少还要向碗里增加几个细菌?若最后不能合并成一个细菌,输出-1,否则输出最少要加入的细菌个数
题解:优先队列逐个处理即可
#include<iostream> #include<string> #include<string.h> #include<algorithm> #include<map> #include<queue> #define mx 0x3f3f3f3f #define ll long long using namespace std; ll gcd(ll a, ll b)//最大公约数 return b == 0 ? a : gcd(b, a % b); ll lcm(ll a, ll b)//最小公倍数 return a / gcd(a, b) * b; priority_queue<ll,vector<ll>,greater<ll> > p; int main() ll n; scanf("%lld",&n); for(int i=0;i<n;i++) ll temp; scanf("%lld",&temp); p.push(temp); ll flag=0,cnt=0; while(p.size()!=1) ll now=p.top(); p.pop(); if(p.size()==1) if(lcm(now,p.top())!=p.top()) flag=1; break; if(now==p.top()) now=now+p.top(); p.pop(); p.push(now); else cnt++; now=now*2; p.push(now); if(flag==1) printf("-1\n"); else printf("%lld\n",cnt); return 0;
D、
题意:给你nn个数,你要给出不同的组合(a,b)(a,b)使得a∗b=A[i]a∗b=A[i],不能重复,但是(a,b)(a,b)和(b,a)(b,a)不同
题解:按照输入顺序枚举每一个数的因子,枚举到一个因子num[i]之后就退出,同时用vis[]反向标记一下这个数,下一次再次遇到这个数,就从上一次的因子num[i]+1继续枚举
用pair数组保存每一个数的一对因子
#include<iostream> #include<algorithm> #include<math.h> #include<string> #include<string.h> #include<vector> #include<utility> #include<map> using namespace std; int vis[10000005],num[10000005];//vis反向标记,用num保存一个因子 pair<int,int>p[200005]; int a[200005]; int n; int solve() for(int i=0;i<n;i++) if(vis[a[i]]==1) vis[a[i]]=0; p[i].first=a[i]/num[a[i]]; p[i].second=num[a[i]]; continue; int flag=0; for(int j=num[a[i]]+1;j<=sqrt(a[i]);j++)//对于每个数从最小的因子开始找,找到一对就退出,下一次再次遇到这个数就从num[a[i]]+1开始找因子 if(a[i]%j==0) flag=1; num[a[i]]=j;//num只存一个因子即可 if(a[i]/j!=j) vis[a[i]]=1;//反向标记,例如第一次找到一组[1,3],用vis标记[3,1]的存在 p[i].first=j; p[i].second=a[i]/j; break;//对于每个数,找到一对因子就退出 if(flag==0) return 0; return 1; int main() scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); num[a[i]]=0;//初始化a[i]的因子为0 if(solve()) printf("YES\n"); for(int i=0;i<n;i++) printf("%d %d\n",p[i].first,p[i].second ); else printf("NO\n");
F. Tickets
题意:有n次询问每次询问给一个数x,且x自动补全六位ABCDEF(可以有前导零),一个数的不幸运值=abs((D+E+F)-(A+B+C)),求出每个在这个数之前比自己不幸运值低的数的个数
题解:提前预处理所有数的不幸运值,然后统计比这个不幸运值低的数的个数
#include<iostream> #include<string> #include<string.h> #include<algorithm> #include<map> #define mx 0x3f3f3f3f #define ll long long using namespace std; int a[1000005],cnt[300]; ll gcd(ll a, ll b)//最大公约数 return b == 0 ? a : gcd(b, a % b); int num(int i) int x=0, y=0; int xx=0,yy=0; x=i%1000; y=i/1000; while(x) int temp=x; x=x/10; xx=xx+temp%10; while(y) int temp=y; y=y/10; yy=yy+temp%10; return abs(xx-yy); int main() int x; memset(cnt, 0, sizeof(cnt)); for(int i=0; i<1000000; i++) a[i] = 0; x = num(i); cnt[x]++; for(int j=0; j<x; j++) a[i]+=cnt[j]; int n; scanf("%d", &n); while(n--) scanf("%d", &x); printf("%d\n", a[x]); return 0;
H. Theater Square
题意:有一个矩形,挖掉一个小矩形之后用1*2的方块填充这个矩形,填充不完整的地方(会留有一些1*1)需要将1*2的方块打碎成两块用来填充,问打碎多少块1*2的方块
模拟即可
#include<iostream> #include<string> #include<string.h> #include<algorithm> #include<map> #define mx 0x3f3f3f3f #define ll long long using namespace std; int a[1000005],cnt[300]; ll gcd(ll a, ll b)//最大公约数 return b == 0 ? a : gcd(b, a % b); int num(int i) int x=0, y=0; int xx=0,yy=0; x=i%1000; y=i/1000; while(x) int temp=x; x=x/10; xx=xx+temp%10; while(y) int temp=y; y=y/10; yy=yy+temp%10; return abs(xx-yy); int main() int x; memset(cnt, 0, sizeof(cnt)); for(int i=0; i<1000000; i++) a[i] = 0; x = num(i); cnt[x]++; for(int j=0; j<x; j++) a[i]+=cnt[j]; int n; scanf("%d", &n); while(n--) scanf("%d", &x); printf("%d\n", a[x]); return 0;
I
题意:对一组本来连续的数,现在缺失了几个,问你最少缺失了几个
#include<iostream> #include<string> #include<string.h> #include<algorithm> #define mx 0x3f3f3f3f #define ll long long using namespace std; ll a[1005]; int main() ll n; scanf("%lld",&n); for(int i=0;i<n;i++) scanf("%lld",&a[i]); sort(a,a+n); int cnt=0; for(int i=1;i<n;i++) cnt=cnt+a[i]-a[i-1]-1; printf("%d\n",cnt);
J
题意:多少组w、h的比例满足x/y,要求w<=a&&h<=b
题解:将x/y化成最简分数,答案就是min(a/x,b/y);
#include<iostream> #include<string> #include<string.h> #include<algorithm> #define mx 0x3f3f3f3f #define ll long long using namespace std; ll gcd(ll a, ll b)//最大公约数 return b == 0 ? a : gcd(b, a % b); int main() ll a,b,x,y,xx; scanf("%lld%lld%lld%lld",&a,&b,&x,&y); xx=gcd(x,y); x=x/xx; y=y/xx; printf("%lld\n",min(a/x,b/y));
K
题意:可以将n个数进行区间分割要求每个区间的中位数>=m问最多可以分成多少个区间
题解:先将所有数从小到大排序,找到第一个满足条件的中位数,之后的所有数都满足条件
#include<iostream> #include<string> #include<string.h> #include<algorithm> #include<map> #include<queue> #define mx 0x3f3f3f3f #define ll long long using namespace std; ll gcd(ll a, ll b)//最大公约数 return b == 0 ? a : gcd(b, a % b); ll lcm(ll a, ll b)//最小公倍数 return a / gcd(a, b) * b; priority_queue<ll,vector<ll>,greater<ll> > p; int a[5005]; int main() int n,m; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); int len=0,now=0,cnt=0; for(int i=0;i<n;i++) if(a[i]>=m) break; len++; for(int i=len;i<n;i++) if(a[i]>=m&&len==now) cnt++; cnt=cnt+n-(i+1); break; else now++; printf("%d\n",cnt); return 0;
以上是关于gym 101911的主要内容,如果未能解决你的问题,请参考以下文章