Qbxt 模拟赛&&day-8
/*
今天的题目还是比较不错的.
今天考的很烂还是依旧的弱.
快考试了加油吧.
Bless all.
*/
注:所有题目的时间限制均为 1s,内存限制均为 256MB。
1.第K小数 (number.cpp/c/pas)
【问题描述】
有两个正整数数列,元素个数分别为N和M。从两个数列中分别任取一个数 相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少。
【输入格式】
输入文件名为number.in。
输入文件包含三行。
第一行为三个正整数N,M和K。
第二行为N个正整数,表示第一个数列。
第三行为M个正整数,表述第二个数列。
【输出格式】
输出文件名为number.out。
输出文件包含一行,一个正整数表示第K小数。
【输入输出样例1】
number.in
2 3 4
1 2
2 1 3
number.out
3
【输入输出样例2】
number.in
5 5 18
7 2 3 5 8
3 1 3 2 5
number.out
16
【数据规模与约定】
![这里写图片描述](https://img-blog.csdn.net/20161110205658499)
![这里写图片描述](https://img-blog.csdn.net/20161110205712476)
/*
二分答案.
O((n+m)logk).
然而本蒟蒻一开始只能暴力.
其实一开始也想到这个单调性了.
但想了想ans并不单调啊.
然后就跪了orz.
二分找下界.
检验的时候因为确定了一个序列之后
另一个序列的元素就单调了.
so 我们二分一个答案
就可以计算出比它小的数的个数.
这个显然是单调的.
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXM 25000001
#define MAXN 200001
#define LL long long
using namespace std;
LL n,m,k;
LL a[MAXN],b[MAXN],tot,ans;
LL read()
{
LL 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*10+ch-48,ch=getchar();
return x*f;
}
bool check(LL x)
{
int p=m;tot=0;
for(int i=1;i<=n;i++)
{
while(p&&a[i]*b[p]>=x) p--;
tot+=p;
}
if(tot>=k) return true;
return false;
}
inline void erfen(LL l,LL r)
{
LL mid;
while(l+1<r)
{
mid=(l+r)>>1;
if(check(mid)) ans=mid,r=mid;
else l=mid;
}
cout<<l;
}
int main()
{
freopen("number.in","r",stdin);
freopen("number.out","w",stdout);
n=read(),m=read(),k=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=m;i++) b[i]=read();
sort(a+1,a+n+1),sort(b+1,b+m+1);
erfen(0,a[n]*b[m]);
return 0;
}
2. dwarf tower (dwarf.cpp/c/pas)
【问题描述】
Vasya在玩一个叫做”Dwarf Tower”的游戏,这个游戏中有n个不同的物品, 它们的编号为1到n。现在Vasya想得到编号为1的物品。 获得一个物品有两种方式:
1. 直接购买该物品,第i件物品花费的钱为ci
2. 用两件其他物品合成所需的物品,一共有m种合成方式。
请帮助Vasya用最少的钱获得编号为1的物品。
【输入格式】
第一行有两个整数n,m(1<=n<=10000,0<=m<=100000),分别表示有n种物品以 及m种合成方式。
接下来一行有n个整数,第i个整数ci表示第i个物品的购买价格,其中 0<=ci<=10^9。
接下来m行,每行3个整数ai,xi,yi,表示用物品xi和yi可以合成物品ai,其 中(1<=ai,xi,yi<=n; ai<>xi, xi<>yi, yi<>ai)
【输出格式】
一行,一个整数表示获取物品 1 的最少花费。
输入样例:
5 3
5 0 1 2 5
5 2 3
4 2 3
1 4 5
输出样例:
2
【数据规模与约定】
60%的数据, n<=100
100%的数据, n<=10000, m<=100000
/*
75.
愚蠢的我建了一棵树.
还能自动判环2333.
但不知道为什么会W.
望路过大神指教.
*/
#include<iostream>
#include<cstdio>
#include<vector>
#define MAXN 10001
using namespace std;
int w[MAXN],n,m,f[MAXN];
vector<int>son[MAXN];
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*10+ch-48,ch=getchar();
return x*f;
}
inline int slove(int u)
{
if(f[u]) return f[u];
f[u]=w[u];
for(int i=0;i<son[u].size();i+=2)
f[u]=min(w[u],slove(son[u][i])+slove(son[u][i+1]));
return f[u];
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
int x,y,z;
n=read(),m=read();
for(int i=1;i<=n;i++) w[i]=read();
if(!m)
{
printf("%d",w[1]);
return 0;
}
for(int i=1;i<=m;i++)
{
x=read(),y=read(),z=read();
son[x].push_back(y),son[x].push_back(z);
}
cout<<slove(1);
return 0;
}
/*
spfa松弛.
一开始也想这样做来着.
但是建图的时候傻眼了.
其实三个点的话就那两个点作为(u,v).
另一个点辅助更新就好了.
一开始让所有点都入队
是为了保证能够正确松弛.
*/
#include<iostream>
#include<cstdio>
#include<queue>
#define MAXN 10001
using namespace std;
int n,m,dis[MAXN],head[MAXN],cut;
bool b[MAXN];
queue<int>q;
struct data{int v,next,x;}e[MAXN*20];
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*10+ch-48,ch=getchar();
return x*f;
}
inline void add(int v,int u,int x)
{
e[++cut].v=v;
e[cut].next=head[u];
e[cut].x=x;
head[u]=cut;
}
inline void bfs()
{
int u;
for(int i=1;i<=n;i++) b[i]=true;
while(!q.empty())
{
u=q.front();q.pop();b[u]=false;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v,x=e[i].x;
if(dis[v]>dis[x]+dis[u])
{
dis[v]=dis[x]+dis[u];
if(!b[v]) b[v]=true,q.push(v);
}
}
}
}
int main()
{
freopen("dwarf.in","r",stdin);
freopen("dwarf.out","w",stdout);
int x,y,z;
n=read(),m=read();
for(int i=1;i<=n;i++) dis[i]=read(),q.push(i);
if(!m)
{
printf("%d",dis[1]);
return 0;
}
for(int i=1;i<=m;i++)
{
x=read(),y=read(),z=read();
add(x,y,z),add(x,z,y);
}
bfs();
printf("%d",dis[1]);
return 0;
}
3. abcd (abcd.cpp/c/pas)
【问题描述】
有4个长度为N的数组a,b,c,d。现在需要你选择N个数构成数组e,数组e满足 a[i]≤e[i]≤b[i]以及
并且使得最大。
【输入格式】
输入文件名为abcd.in。
输入文件共 N+1 行。
第 1 行包含1个正整数N。
第 i+1 行包含4个整数a[i],b[i],c[i],d[i]。
【输出格式】
输出文件名为abcd.out。
输出共1行,包含1个整数,表示所给出公式的最大值。
输入数据保证一定有 解。
【输入输出样例1】
abcd.in
5
- 1 1 2 5
-2 2 1 2
0 1 1 3
-2 -1 3 10
-2 2 3 9
abcd.out
2
【输入输出样例2】
abcd.in
10
1 10 1 7
-10 10 2 0
-10 10 2 2
-10 10 2 0
1 10 1 0
-10 10 2 0
10 10 2 0
1 10 1 0
-10 10 2 0
1 10 1 0
abcd.out
90
【输入输出样例3】
abcd.in
10
1 10 1 0
-10 10 2 2
-10 10 2 2
-10 10 2 2
1 10 1 0
-10 10 2 2
-10 10 2 2
1 10 1 0
-10 10 2 2
1 10 1 0
abcd.out
-4
【数据规模与约定】
对于 20%的数据, N≤10, -2≤a[i]
/*
20.
纯暴力(剪枝忽视掉).
*/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define MAXN 201
using namespace std;
int a[MAXN],b[MAXN],c[MAXN],d[MAXN],n,ans=-1e9,tot,s[MAXN];
int sum1[MAXN],sum2[MAXN];
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*10+ch-48,ch=getchar();
return x*f;
}
inline void dfs(int t,int tot,int sum)
{
if(t==n+1)
{
if(!tot)
ans=max(ans,sum);
return ;
}
for(int i=b[t];i>=a[t];i--)
{
if(tot+i*c[t]+sum1[t+1]<0) continue;
dfs(t+1,tot+i*c[t],sum+i*d[t]);
}
return ;
}
int main()
{
freopen("abcd.in","r",stdin);
freopen("abcd.out","w",stdout);
n=read();
for(int i=1;i<=n;i++)
a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read();
for(int i=n;i>=1;i--) sum1[i]=sum1[i+1]+b[i]*c[i];
dfs(1,0,0);
printf("%d",ans);
return 0;
}
/*
60.
f[i][y]表示从n到i构成y的最大值.
从1点跑固定终点的单源DAG.
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#define MAXN 202
#define MAXM 100001
using namespace std;
int a[MAXN],b[MAXN],c[MAXN],d[MAXN],n,tot;
int sum1[MAXN],sum2[MAXN],f[MAXN][MAXM*2+100],INF;
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*10+ch-48,ch=getchar();
return x*f;
}
inline int dfs(int t,int tot)
{
if(f[t][tot]!=INF) return f[t][tot];
if(t==n+1)
{
if(tot==MAXM-1) return 0;
return INF;
}
for(int i=b[t];i>=a[t];i--)
{
//if(tot+i*c[t]+sum1[t+1]<0) continue;
f[t][tot]=max(f[t][tot],dfs(t+1,tot+i*c[t])+i*d[t]);
}
return f[t][tot];
}
int main()
{
freopen("abcd.in","r",stdin);
freopen("abcd.out","w",stdout);
memset(f,-127/3,sizeof f);INF=f[0][0];
n=read();
for(int i=1;i<=n;i++)
a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read();
//for(int i=n;i>=1;i--) sum1[i]=sum1[i+1]+b[i]*c[i];
printf("%d",dfs(1,MAXM-1));
return 0;
}
/*
正解多重背包.
想不到吖想不到.
对于∑e[i]*c[i]=0 ①
和ans=∑b[i]*e[i] ②
因为e[i]=[a[i],b[i]]等价于[0,b[i]-a[i]]+a[i];
so 问题转化为使得
∑(b[i]-a[i])*c[i]+∑a[i]*c[i]=0
且∑(b[i]-a[i])*d[i]+∑a[i]*d[i]最大.
然后∑a[i]*c[i]和∑a[i]*d[i]是可以计算的.
令V=∑a[i]*c[i](V<0),s[i]=b[i]-a[i].
so 问题转化为在体积为-V的背包中取物品s[i]求最大值.
可以从1(or n)跑固定起点和终点的DAG
or二进制拆01背包or四边形单调队列等等...
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 201
#define MAXM 100001
using namespace std;
int n,a[MAXN],b[MAXN],c[MAXN],d[MAXN];
int V,ans1,tot,w[MAXM],v[MAXM],f[MAXM];
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*10+ch-48,ch=getchar();
return x*f;
}
inline int slove()
{
V*=-1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=b[i];j<<=1)
b[i]-=j,w[++tot]=d[i]*j,v[tot]=c[i]*j;
if(b[i]) w[++tot]=d[i]*b[i],v[tot]=c[i]*b[i];
}
f[0]=0;
for(int i=1;i<=tot;i++)
for(int j=V;j>=v[i];j--)
f[j]=max(f[j],f[j-v[i]]+w[i]);
return f[V];
}
int main()
{
freopen("abcd.in","r",stdin);
freopen("abcd.out","w",stdout);
n=read();memset(f,-127/3,sizeof f);
for(int i=1;i<=n;i++)
a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read(),
V+=a[i]*c[i],b[i]-=a[i],ans1+=a[i]*d[i];
printf("%d",slove()+ans1);
return 0;
}
Qbxt 模拟赛&&day-8的更多相关文章
- QBXT模拟赛2
总结 期望得分:\(100 + 40 + 0 = 140\) 实际得分:\(0 + 0 + 0 = 0\) 鬼知道为什么我代码没有交上..自测\(10 + 50 + 0\)--这是心态爆炸的一场考试 ...
- QBXT模拟赛1
总结 期望得分:\(100 + 80 + 10 = 190\) 实际得分:\(90 + 80 + 10 = 180\) 这是在清北的第一场考试,也是在清北考的最高的一次了吧..本来以为能拿\(190\ ...
- 4.28 QBXT模拟赛
NOIP2016提高组模拟赛 ——By wangyurzee7 中文题目名称 迷妹 膜拜 换数游戏 英文题目与子目录名 fans mod game 可执行文件名 fans mod game 输入文件名 ...
- 2017.10.3 QBXT 模拟赛
题目链接 T1 模拟 #include <cstring> #include <cstdio> #define N 105000 int L,R; char s[N]; int ...
- 2017.10.7 QBXT 模拟赛
题目链接 T1 容斥原理,根据奇偶性进行加减 #include<iostream> #include<cstdio> using namespace std; typedef ...
- 2017.10.6 QBXT 模拟赛
题目链接 T1 Sort 一下与原数组比较 ,若有两个数或者没有数发生位置交换 ,则输出YES ,否则输出NO #include <algorithm> #include <ccty ...
- 2017.10.5 QBXT 模拟赛
题目链接 T1 从小到大排序,用sum记录前缀和,然后枚举1~n个数 ,如果当前的前缀和 + 1小于a[i]的话 那么 sum + 1永远不可能拼出来 直接输出sum + 1 ,否则统计前缀和.最后如 ...
- 2017.10.4 QBXT 模拟赛
题目链接 T1 维护一个单调栈 #include <iostream> #include <cstdio> #define N 500000 #define rep(a,b,c ...
- 2017.10.2 QBXT 模拟赛
题目链接 T1 我们所要求得是(a*b)|x 也就是 使(a*b)的倍数小于x的个数之和 1<=x<=n 我们可以 找一个c使得 (a*b*c)<=x 由于我们所求的是一个三元有序对 ...
- 2017.10.1 QBXT 模拟赛
题目链接 T1 枚举右端点,前缀和优化.对于当前点x,答案为 sum[x][r]-sum[x][l-1]-(sum[z][r]-sum[z][l-1]) 整理为 sum[x][r]-sum[z][r] ...
随机推荐
- vue技术分享之你可能不知道的7个秘密
本文是vue源码贡献值Chris Fritz在公共场合的一场分享,觉得分享里面有不少东西值得借鉴,虽然有些内容我在工作中也是这么做的,还是把大神的ppt在这里翻译一下,希望给朋友带来一些帮助. 一.善 ...
- 【计数】Simple Addition Expression
[来源] 2008年哈尔滨区域赛 [题目链接]: http://acm.hdu.edu.cn/showproblem.php?pid=2451 [参考博客]: HDU 2451 Simple Addi ...
- QPushButton样式
QPushButton:hover:!pressed { border: 1px solid #434E7A; }
- java实现spark常用算子之mapPartitionsWithIndex
import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.a ...
- CSS 使用calc()获取当前可视屏幕高度
来自:https://blog.csdn.net/qq_32063079/article/details/89766442 先了解一下CSS3的相对长度单位(参考详细教程) : 相对长度单位指定了一个 ...
- vue2.0+按需引入element-ui报错
项目使用vue脚手架自动生成的,vue版本为^2.5.16.项目中需要按需使用element-ui,根据element-ui的官方文档,一开始在babel.config.js文件中修改配置 modul ...
- Ubuntu下编译boost for Android
下载https://github.com/moritz-wundke/Boost-for-Android 解压后进入目录 运行 ./build-android.sh $(NDK_ROOT) NDK_R ...
- php实现雪花算法(ID递增)
雪花算法简单描述: 最高位是符号位,始终为0,不可用. 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序. 10位的机器标识,10位的长度最 ...
- greenlet、gevent:历史悠久的用于处理并发的模块
greenlet介绍 greenlet是用C语言编写的一个模块,然后让python调用,目的就是为了让python支持协程. A "greenlet" is a small ind ...
- DBUtils封装数据库返回对象的各种方法
①ArrayHandler: 将查询结果的第一行数据,保存到Object数组中 ②ArrayListHandler 将查询的结果,每一行先封装到Object数组中,然后将数 ...