一次不知道该叫什么的模拟赛和一篇不知道该起什么标题的补题
来源:互联网 发布:外国人代购淘宝 编辑:程序博客网 时间:2024/05/01 09:51
这套题前部分略水,但T2的正解(虽然A了),T5的优化,以及T6,在下都束手无策,还需要好好学习啊。。。。自己还是太水了。。。。
A题
模拟。。。直接贴代码了。。。、
#include<iostream>#include<string.h>#include<math.h>#include<stdio.h>#include<algorithm>using namespace std;int n;string h;int a[30],cnt=0;int main(){freopen("trener.in","r",stdin);freopen("trener.out","w",stdout);cin>>n;getchar();for(int i=1;i<=n;i++)cin>>h,a[h[0]-'a']++;for(int i=0;i<=25;i++)if(a[i]>=5)cout<<(char)(i+'a'),cnt++;if(cnt==0)cout<<"PREDAJA";}
B题
n个人分m个蛋糕,求最小切刀数
啊啊啊其实正解很简单啊,从头到尾一个个模拟就好了,然而人比较笨虽然A了但就是死活想不到
cin>>n>>m;for(int i=0;i<=n*m;i+=n) if(i%m!=0) ans++;cout<<ans<<endl;
本人做法挺离谱的,有递归做solve(n,m),n->当前剩的面包,m->要分的人
当n>=m时,说明每人吃超过1块面包,n=n%m;
当m>n时,处理此时应该把每个面包分成多少份x,和给每个人应发多少份y,先给x/y *n个人分够他们的量,那么m=m-x/y*n,同时ans+=x/y*n;
如果n=0,说明没有面包再分了,没必要做了,直接return;
如果m=0,说明没有人必要分了,但我还保留了这n块“空面包”,它们实际没必要被切,那么ans-=n;
是不是很严(fu)谨(za)啊。。。
#include<iostream>#include<math.h>#include<string.h>#include<stdio.h>#include<algorithm>using namespace std;int gcd(int a,int b){if(b==0)return a;return gcd(b,a%b);}int lcm(int a,int b){return a*b/gcd(max(a,b),min(a,b));}int ans,n,m,gong,mei,qie;void jie(int n1,int m1){if(n1==0)return ;if(m1==0){ans-=n1;return ;}if(n1>=m1){int gong=lcm(n1,m1),qie=gong/n1,mei=gong/m1;int zhi=(mei/qie)*m1,yu=n1-zhi;jie(yu,m1);}else{int gong=lcm(n1,m1),qie=gong/n1,mei=gong/m1;ans+=qie/mei*n1;jie(n1,m1-qie/mei*n1);}}int main(){freopen("kusac.in","r",stdin);freopen("kusac.out","w",stdout);scanf("%d%d",&n,&m);jie(n,m);cout<<ans;}
C题
给出一幅N*N的地图,每个格子上都有一个权值,求出有多少对矩形“对角”(即只有一个公共点)而且权值和相等。
先做一遍前缀和sum[i][j]表示从(1,1)到(i,j),那么我们就可以通过O(4)的复杂度求出任意一个矩形内的权值和。
枚举点(i,j)的右下点作为“对点”,先从(1,1)到(i,j)把所有以此为右下角的矩形都枚举一边,并把它们在对应值数组里个数+1,然后再枚举以这个点作为左上角的矩形们,并答案+=它在对应数组里的值,及这个值在左上方矩形(即以(i,j)为右下角的顶点的矩形们)出现过的次数,对与以(i,j)右上角,左下角的矩形做法也是同理。
注意在清空访问值次数时,不能直接memset,会很慢,应该在更新值出现次数时记录一下,最后清零时直接访问改即可。
#include<iostream>#include<string.h>#include<math.h>#include<stdio.h>#include<algorithm>using namespace std;int map[55][55],sum[55][55];int in[5000050];int g[2700];int getsum(int x1,int y11,int x2,int y2){return sum[x2][y2]-sum[x2][y11-1]-sum[x1-1][y2]+sum[x1-1][y11-1];}int ans=0,n,gh[2555];int main(){freopen("ratar.in","r",stdin);freopen("ratar.out","w",stdout); scanf("%d",&n);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&map[i][j]),sum[i][j]=map[i][j];for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)sum[i][j]+=sum[i-1][j];for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)sum[i][j]+=sum[i][j-1];for(int i=1;i<n;i++){for(int j=1;j<n;j++){int f,cnt=0;for(int i1=1;i1<=i;i1++)for(int j1=1;j1<=j;j1++)f=getsum(i1,j1,i,j)+2500000,in[f]++,gh[++cnt]=f;for(int i1=i+1;i1<=n;i1++)for(int j1=j+1;j1<=n;j1++)ans+=in[getsum(i+1,j+1,i1,j1)+2500000];for(int i1=1;i1<=cnt;i1++)in[gh[i1]]=0;cnt=0;for(int i1=i+1;i1<=n;i1++)for(int j1=1;j1<=j;j1++)f=getsum(i+1,j1,i1,j)+2500000,in[f]++,gh[++cnt]=f;for(int i1=1;i1<=i;i1++)for(int j1=j+1;j1<=n;j1++)ans+=in[getsum(i1,j+1,i,j1)+2500000];for(int i1=1;i1<=cnt;i1++)in[gh[i1]]=0;}}cout<<ans<<endl;}
D题
一个很蠢的贼(而且还是被政府雇佣的。。。),他带了一堆包,都有容量,还有一堆珠宝,每个珠宝都有一定体积和一定价值,然而!!他只打算在每个包里只装一个珠宝。。。于是这道题从一个很好的背包问题变成了一个很蠢的贪心。。。
以一个结构体,存入所有的珠宝和背包,背包的价值设为-1以区别。按照容量按照小值sort一下,如果价值不为-1那么把这个值push进优先队列(最大值优先)里,如果是-1,
如果队列不为空,ans+=队首,并且将其出队。
#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>#include<math.h>#include<queue>#include<vector>using namespace std;priority_queue<int> q;struct ba{int v,room;}bag[600500];int cmp(ba a,ba b){return (a.room==b.room)?a.v>b.v:a.room<b.room;}int n,m;long long ans;int main(){freopen("lopov.in","r",stdin);freopen("lopov.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d%d",&bag[i].room,&bag[i].v);for(int i=1;i<=m;i++)scanf("%d",&bag[i+n].room),bag[i+n].v=-1;sort(bag+1,bag+m+n+1,cmp);for(int i=1;i<=n+m;i++){if(bag[i].v!=-1)q.push(bag[i].v);elseif(!q.empty())ans+=q.top(),q.pop();}cout<<ans<<endl;}
E题
给出一堆数,请计算i*(因数中含有I的数的个数)
我写的是裸的(做法是那种一读题就懂的),然而T了1个点。。。。
void init(){for(int i=2;i<=2000000;i++){if(prim[i]==0)for(int j=1;i*j<=2000000;j++)if(prim[i*j]==0) prim[i*j]=i;}}void get(int x){ size=1;tmp[0]=1; while(x>1){ int p=prim[x]; int pow=1; for(;x>1&&prim[x]==p;x/=p) pow++; for(int i=size;i<size*pow;i++) tmp[i]=tmp[i-size]*p; size*=pow; } }
加了马大佬的这个优化,就能过了。
他的这个算法复杂度小于o(根号n),思路是用prim[i]存i的第一个质因数,然后一直分解到j并将所有j的i倍数(得小于等于它含i的个数)一解决,紧接着再递归处理,并把他们的i倍加进去就好了。
F题
后缀数组还不会,题解也看不太懂。。明天继续连载。。。
- 一次不知道该叫什么的模拟赛和一篇不知道该起什么标题的补题
- 不知道该起个什么标题(0)
- 不知道该叫啥标题
- 不知道该写什么
- 不知道该写什么
- 不知道该说什么
- 第一篇不知道该写点什么东东
- 第一篇 不知道该说些什么!
- 不知道起什么标题 01
- 【2013.1.14】不知道该起个什么名字,就叫小明的爸爸吧。——AbstractFactory
- 不知道起什么标题的笔记内容
- 标题の我也不知道该叫什么
- 不知道该写些什么。
- 不知道该说什么好
- 真不知道该说什么好
- 不知道该说些什么了
- 不知道该写些什么
- 想你,却不知道该和你说什么,
- Mybatis 中#与$的区别
- 分析weblogic数据库线程池无可用连接的问题
- 集中式VS分布式
- 随机连接
- 数据结构绪论-逻辑结构与物理结构
- 一次不知道该叫什么的模拟赛和一篇不知道该起什么标题的补题
- 算法训练 判定数字
- 【BZOJ 1011】[HNOI2008]遥远的行星
- 最长对称子串 -- 天梯模拟
- linux之apt与dpkg安装包管理工具的区别
- vmware-nat模式下网络模型
- HDU 4869Turn the pokers
- android基础----px 与 dp, sp换算公式
- Netty之源代码解析