Gym 101482C Cent Savings

简单的dp

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=2200;
ll dp[maxn][22],sum[maxn]; int main(){
int n,m;
scanf("%d%d",&n,&m);m++;
for(int i=1;i<=n;i++){
scanf("%lld",&sum[i]);
sum[i]+=sum[i-1];
}
memset(dp,inf64,sizeof(dp));
dp[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=min(i,m);j++){
for(int k=0;k<i;k++){
ll val=sum[i]-sum[k];
val=(val+5)/10*10;
dp[i][j]=min(dp[i][j],dp[k][j-1]+val);
}
}
}
ll ans=inf64;
for(int i=1;i<=m;i++) ans=min(ans,dp[n][i]);
printf("%lld\n",ans);
return 0;
}
/*
5 1
13 21 55 60 42
5 2
1 1 1 1 1
*/

Gym 101482D Digi Comp II

拓扑,注意细节

#include <bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
ll num[maxn],n,m;
int cur[maxn],L[maxn],R[maxn],in[maxn];
void tp(){
queue<int>que;
while(!que.empty()) que.pop();
for(int i=1;i<=m;i++){
if(in[i]==0) que.push(i);
}
while(!que.empty()){
int u = que.front();que.pop();
int lc=L[u],rc=R[u];
if(cur[u]) num[lc]+=num[u]/2,num[rc]+=(num[u]+1)/2;
else num[lc]+=(num[u]+1)/2,num[rc]+=num[u]/2;
in[lc]--;
if(in[lc]==0) que.push(lc);
in[rc]--;
if(in[rc]==0) que.push(rc);
}
}
int main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++){
char s[10];
scanf("%s%d%d",s,&L[i],&R[i]);
in[L[i]]++,in[R[i]]++;
if(s[0]=='L') cur[i]=0;
else cur[i]=1;
}
num[1]=n;
tp();
for(int i=1;i<=m;i++){
if(num[i]&1) cur[i]^=1;
if(cur[i]==0) printf("L");
else printf("R");
}
printf("\n");
return 0;
}

E - Euclidean TSP Gym - 101482E

这个题目不是我写的,好像只要看清楚题目,就会了?三分

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <map>
#include <math.h>
#include <string>
#include <cstring>
#define fir first
#define sec second
using namespace std;
typedef long long ll;
const int maxn = 1e4+7; double n,p,s,v;
double k1,k2,res;
double m = sqrt(2); double val(double x) {
return k1*pow(k2,x)+res*(1+1/x);
} int main() {
cin>>n>>p>>s>>v;
k1 = n/p/1e9;
k2 = pow(log(n)/log(2),m);
res = s/v;
double l = 0 ,r = 1e10; for(int i=0;i<100;i++) {
double len = (r-l)/3.0;
double lmid = len+l;
double rmid = lmid+len;
if(val(lmid) > val(rmid)) l = lmid;
else r = rmid;
}
printf("%.7f %.7f\n",val(l),l);
return 0;
}
/*
l, r = start, end
epsilon = 1e-6
# 我们自定义的终止条件是区间长度小于1d-6
while l + epsilon < r:
margin = (r - l) / 3.0
m1 = l + margin
m2 = m1 + margin
if f(m1) <= f(m2):
r = m2
else:
l = m1
*/

Gym 101482F Finding Lines

随机数,比较奇葩,很少碰到这样的题目

#include<iostream>
#include<cstdlib>
#include<ctime>
#define N 100005
using namespace std;
typedef long long ll;
namespace random {
typedef unsigned ui;
typedef long long ll;
typedef unsigned long long ull;
ui X, Y, Z, W;
void start() {
srand ( (ui) time (NULL) );
X = rand(), Y = X ^ rand(), Z = Y ^ rand();
}
ui RNG61() {
X = X ^ (X << 11);
X = X ^ (X >> 4);
X = X ^ (X << 5);
X = X ^ (X >> 14);
W = X ^ Y ^ Z;
X = Y;
Y = Z;
Z = W;
return Z;
}
int Randint (int mod) {return RNG61() % mod + 1;}
ll Randll(ll mod) {return ((ull)RNG61() << 32 | RNG61()) % mod + 1;}
double Randdouble(int l, int r) {
if(l == r) return l;
if(l > r) swap(l, r);
double ret = RNG61() % (r - l) + l;
double tmp = RNG61();
while(tmp > 1) tmp /= 10;
ret += tmp;
return ret;
}
}
using namespace random;
struct point{
ll x,y;
}a[N];
ll n,p,ans; ll check(ll first,ll second){
ll sum=2;
ll x1=a[first].x-a[second].x;
ll y1=a[first].y-a[second].y;
for(int i=0;i<n;++i){
if(i==first||i==second)continue;
ll x2=a[i].x-a[second].x;
ll y2=a[i].y-a[second].y;
if(x1*y2-x2*y1==0)sum++;
}
if(sum*100-p*n>=0)return 1;
return 0;
}
int main(void){
start();
while(cin>>n>>p){
for(ll i=0;i<n;++i)
cin>>a[i].x>>a[i].y;
if(n<=2){
cout<<"possible\n";
continue;
}
ans=0;
for(ll t=0;t<100;++t){
ll first=Randint(n-1),second=Randint(n-1);
if(first==second)continue;
ans+=check(first,second);
// if(ans) printf("first=%lld second =%lld\n",first,second);
}
if(ans)cout<<"possible\n";
else cout<<"impossible\n";
}
}

Gym 101482G Gathering 三分+切比雪夫距离

题目大意:

给你n个点,给定每一个点的坐标,自己定一个中心城市,要求每一个点到这个中心城市的曼哈顿距离要小于等于d,求这个中心城市到每一个城市的曼哈顿距离和最小。

题解:

写这个题目之前要学习一下 切比雪夫距离,学习博客->切比雪夫距离

把切比雪夫距离 \((x,y)\) 转化成曼哈顿距离 \((x+y,x-y)\)

把曼哈顿距离 \((x,y)\) 转化为切比雪夫距离 \((\frac{x+y}{2},\frac{x-y}{2})\)

其次就是要知道如果没有这个d的限制,则最小的应该是x的中位数和y的中位数的那个点。

  • 首先通过曼哈顿距离转化成切比雪夫距离,然后求出上下左右四个边界。

  • 然后因为没有d的限制最小的是x的中位数和y的中位数,所以要三分这个x的距离,当确定这个x之后,怎么求y呢?

    • 第一种方法,三分求y,因为y也是中位数是一个峰值,但是这样会T在37组。
    • 第二种方法,直接判断此时的x对应的y的最小值和最大值,如果中位数在 \(ymin\) 和 \(ymax\) 之间,则直接取中位数,如果 \(ymax < ymid\) 则取\(ymax\) ,如果 \(ymin>ymid\) 则取 \(ymin\)。
  • 最后就是求答案,注意三分的写法。

    (1) 这个 其实很简单,但是我傻逼了,想了好久。。。

其实就是这个xx要转化成切比雪夫后要满足四个边界要求

(xx,y)曼哈顿 转化成切比雪夫(xx+y,xx-y)

l<xx+y<r 和 down<xx-y<up 求出这个y的范围

#include <bits/stdc++.h>
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
ll x[maxn],y[maxn],gx[maxn],gy[maxn],midy,n,d;
ll down,up,lc,rc;
ll solve(ll xx){
ll yup=min(xx-down,rc-xx);//这里看解释(1)
ll ydn=max(xx-up,lc-xx);
if(yup<ydn) return inf64;
ll dy=0,ans=0;
if(midy<=yup&&midy>=ydn) dy=midy;
else if(midy>yup) dy=yup;
else dy=ydn;
for(int i=1;i<=n;i++) ans+=abs(x[i]-xx)+abs(y[i]-dy);
return ans;
} int main(){
scanf("%lld",&n);
down = -inf64,up = inf64;
lc = -inf64,rc = inf64;
for(int i=1;i<=n;i++)scanf("%lld%lld",&x[i],&y[i]);
scanf("%lld",&d);
for(int i=1;i<=n;i++){
down=max(down,x[i]-y[i]-d);
up=min(up,x[i]-y[i]+d);
lc=max(lc,x[i]+y[i]-d);
rc=min(rc,x[i]+y[i]+d);
}
if(down>up||lc>rc) {
printf("impossible\n");
return 0;
}
sort(y+1,y+1+n);midy=y[(n+1)/2];
ll L=(lc+down)/2,R=(rc+up)/2,ans=inf64;
while(L<R-2){
ll l = L + (R-L)/3,ans1=solve(l);
ll r = R - (R-L)/3,ans2=solve(r);
if(ans1>ans2) L=l,ans=min(ans,ans2);
else R=r,ans=min(ans,ans1);
}
for(;L<=R;L++) ans=min(ans,solve(L));
printf("%lld\n",ans);
return 0;
}

Gym 101482H Hyacinth

简单的图论题

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e4+10;
int lc[maxn],rc[maxn];
struct node{
int v,nxt;
node(int v=0,int nxt=0):v(v),nxt(nxt){}
}e[maxn*2];
int head[maxn],cnt,now;
void add(int u,int v){
e[++cnt]=node(v,head[u]);
head[u]=cnt;
e[++cnt]=node(u,head[v]);
head[v]=cnt;
}
void dfs(int u,int pre){
int res=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==pre) continue;
res++;
if(res==1){
lc[v]=rc[u];
rc[v]=++now;
}
else {
lc[v]=lc[u];
rc[v]=++now;
}
dfs(v,u);
}
}
int main(){
int n;
cnt=0,now=2;
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
lc[1]=1,rc[1]=2;
dfs(1,0);
if(n==2){
printf("1 2\n");
printf("1 2\n");
}
else {
for(int i=1;i<=n;i++){
printf("%d %d\n",lc[i],rc[i]);
}
}
return 0;
}

Gym 101482I Indoorienteering 双向搜索

题目大意:

给你一个数n,和一个\(n*n\)的方阵,对于方阵中的 \(d[i][j]\) 表示 \(i\) 到 \(j\) 之间的最短距离。

求遍历n个点,最后回到起点,其他点只走一次的,求距离和是否能达到L。

题解:

就是一个双向搜索,如果不会双向搜索可以看看这个题目->送礼物

因为我是要判断是否可以达到距离和为L,而不是求经过所有的点的最小距离或者说是最大距离或者说是方案数,所以不可以用状压\(dp\) ,必须要进行暴力的搜索来求这个距离和。

为什么这个可以用双向搜索呢,因为我已知这个距离和了,所以要充分利用这个条件。

  • 首先我要把这个划分成两个集合,两个集合大小尽量相等,但是怎么划分这两个集合呢?

    首先我们要明白这个集合是不能随意划分的,不能说前 \(n/2\) 为第一个集合,后面的数自动成为第二个集合。为什么不能呢,假设,n=6,最后满足条件的是 1-4-3-2-5-6 ,但是我把 1 2 3 放到了一个集合,意味着1一定要和2 或者3 直接相连,但是呢这个并不满足条件。

  • 所以这个集合的划分应该暴力来求解。

  • 其次,对于第一个集合,我们是求出这个集合的所有的可能解,然后存下来,这样的话,是不是这个集合的起点和终点必须确定,因为如果不确定,则第一个集合的起点要和第二个集合的终点连边第一个集合的终点要和第二个集合的起点连边,这样的话,这两个距离就无法确定,那么也就不能二分来求答案了。

  • 对于第一个集合的起点是很好确定的,可以任意选一个值,因为你想想啊,每一个点都必须经过,而又是一个圈,所以第一个集合的起点就可以任意定下来,终点就直接枚举即可。

\(bug\) 一定要静下心来找!!!

#include <bits/stdc++.h>
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
ll w[20][20],a[20],b[20],vis[20],n,L,g[maxn];
int cnta,cntb,num=0; void dfs1(int u,int t,ll sum,int now){
// printf("u=%d t=%d sum=%lld now=%d\n",u,t,sum,now);
if(sum>L) return ;
if(now==cnta&&u==t){
g[++num]=sum;
return ;
}
if(u==t) return ; for(int i=2;i<=cnta;i++){
int v=a[i];
if(vis[v]) continue;
vis[v]=1;
dfs1(v,t,sum+w[u][v],now+1);
vis[v]=0;
}
}
int f=0;
void dfs2(int u,ll sum,int now){
// printf("u=%d sum=%lld now=%d\n",u,sum,now);
if(sum>L) return ;
if(now==cntb){
sum+=w[u][1];
if(sum>L) return ;
int t=lower_bound(g+1,g+1+num,L-sum)-g;
if(g[t]+sum==L) f=1;
// printf("b[%d]=%d sum=%lld t=%d g=%d f=%d\n",u,b[u],sum,t,g[t],f);
return ;
}
for(int i=1;i<=cntb;i++){
int v=b[i];
if(vis[v]) continue;
vis[v]=1;
dfs2(v,sum+w[u][v],now+1);
vis[v]=0;
}
} bool judge(int t){
memset(vis,0, sizeof(vis));
vis[1]=1,num=0;
dfs1(1,t,0,1); sort(g+1,g+1+num);
num=unique(g+1,g+1+num)-g-1; // for(int i=1;i<=num;i++) printf("g[%d]=%lld\n",i,g[i]); memset(vis,0, sizeof(vis));
dfs2(t,0,0);
// printf("xxx f=%d\n",f);
return f;
} bool solve(){
for(int i=2;i<=cnta;i++) if(judge(a[i])) return true;
return false;
} int main(){
f = 0;
scanf("%lld%lld",&n,&L);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%lld",&w[i][j]);
}
}
if(n<=3){
ll sum=0;
if(n==2) sum=2*w[1][2];
else sum=w[1][2]+w[2][3]+w[1][3];
if(sum==L) printf("possible\n");
else printf("impossible\n");
return 0;
}
for(int s=0;s<(1<<n);s++){
cnta=0,cntb=0;
for(int j=1;j<=n;j++){
int tmp=1<<(j-1);
if(tmp&s) a[++cnta]=j;
else b[++cntb]=j;
}
if(cnta==n/2&&a[1]==1){
if(solve()){
printf("possible\n");
return 0;
}
}
}
printf("impossible\n");
return 0;
}

Gym 101482J

签到题

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=3e6+10;
map<string,int>mp; int main(){
int n,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
string s;
cin>>s;
mp[s]++;
}
for(int i=1;i<=n;i++){
string s;
cin>>s;
if(mp[s]) ans++,mp[s]--;
}
printf("%d\n",ans);
return 0;
}

Gym 101482K

这个把所有的离散化一下然后暴力求每一个位置开始的解

#include <bits/stdc++.h>
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
const int maxn=2e3+10;
typedef long long ll;
int cur[maxn],num[maxn],a[maxn],v[maxn];
ll val[maxn];
set<ll>st;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
} int main(){
int n,s,t;
scanf("%d%d%d",&n,&s,&t);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),v[i]=a[i];
sort(v+1,v+1+n);
int len = unique(v+1,v+1+n) - v - 1;
for(int i=1;i<=n;i++){
int w=lower_bound(v+1,v+1+len,a[i])-v;
num[w]++;
}
for(int i=1;i<=len;i++){
st.clear();
st.insert(inf64);
for(int j=1;j<=len;j++){
st.insert(v[j]);
cur[j]=num[j];
}
int sum=n,now=v[i];
while(sum){
ll pos = *st.lower_bound(now);
if(pos>=inf64) val[i]+=(0-now+s)%s,now=0;
else {
val[i]+=pos-now,sum--;
int w=lower_bound(v+1,v+1+len,pos)-v;cur[w]--;
if(cur[w]==0) st.erase(pos);
now=(pos+t)%s;
val[i]+=t;
}
}
}
ll sum=0,mins=inf64,maxs=0;
mins=min(mins,val[1]);
ll x=(v[1]-v[len]+s-1)%s;
maxs=max(maxs,x+val[1]);
sum+=(val[1]+val[1]+x)*(x+1)/2;
for(int i=2;i<=len;i++){
x = (v[i]-v[i-1]+s-1)%s;
maxs=max(maxs,x+val[i]);
mins=min(mins,val[i]);
sum+=(val[i]+val[i]+x)*(x+1)/2;
}
ll g=gcd(sum,s);
sum/=g,s/=g;
printf("%lld\n%lld\n%lld/%d\n",mins,maxs,sum,s);
return 0;
}

Northwestern European Regional Contest 2014 Gym - 101482的更多相关文章

  1. codeforces Gym - 101485 D Debugging (2015-2016 Northwestern European Regional Contest (NWERC 2015))

    题目描述: 点击打开链接 这题题意其实很不好理解,你有一个n行的程序,现在程序运行了r时间之后停止了运行,证明此处有一个bug,现在你需要在程序中加printf来调试找到bug所在的位置,你每次加一个 ...

  2. Northwestern European Regional Contest 2016 NWERC ,F题Free Weights(优先队列+Map标记+模拟)

    传送门: Vjudge:https://vjudge.net/problem/Gym-101170F CF: http://codeforces.com/gym/101170 The city of ...

  3. 2015-2016 Northwestern European Regional Contest (NWERC 2015)

    训练时间:2019-04-05 一场读错三个题,队友恨不得手刃了我这个坑B. A I J 简单,不写了. C - Cleaning Pipes (Gym - 101485C) 对于有公共点的管道建边, ...

  4. 2017-2018 Northwestern European Regional Contest (NWERC 2017)

    A. Ascending Photo 贪心增广. #include<bits/stdc++.h> using namespace std; const int MAXN = 1000000 ...

  5. Northwestern European Regional Contest 2017-I题- Installing Apps题解

    一.题意 有一个手机,容量为$C$,网上有$N$个app,每个app有个安装包大小$d_i$,有个安装后的占用空间大小$s_i$,安装app是瞬间完成的,即app的占用空间可以瞬间由$d_i$变成$s ...

  6. 2012-2013 Northwestern European Regional Contest (NWERC 2012)

    B - Beer Pressure \(dp(t, p_1, p_2, p_3, p_4)\)表示总人数为\(t\),\(p_i\)对应酒吧投票人数的概率. 使用滚动数组优化掉一维空间. 总的时间复杂 ...

  7. 2006 ACM Northwestern European Programming Contest C题(二分求最大)

    My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I have a numberN o ...

  8. ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbilisi, November 24, 2010

    ACM ICPC 2010–2011, Northeastern European Regional Contest St Petersburg – Barnaul – Tashkent – Tbil ...

  9. 2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17)

    2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) A 题意:有 n 个时刻 ...

随机推荐

  1. Docker命名空间

    命名空间 命名空间( namespace )是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便利,利用这 特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在独立的操作系 ...

  2. XFS文件系统的备份与恢复

    永久修改主机名:hostnamectl set-hostname oldboy临时修改主机名:hostname xfsdump备份xfsdump -f 备份的文件位置 要备份的分区或者磁盘 免交互备份 ...

  3. stand up meeting 11/26/2015

    part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云  完成UI简易界面布局设计:在UI部分实现释义数据格式转换的实现和测试,使得其与外界接口均标准化为string,具体实现见 ...

  4. 简单的中国MOOC大学列表提取 - Python

    有些时候我们想知道网页中包含哪些具体的信息,比如如下的这个网页, http://www.icourse163.org/university/view/all.htm 我们只想知道自己的学校是否在这个列 ...

  5. mysql创建存储过程及调用

    创建存储过程简单示例: DELIMITER //CREATE PROCEDURE ccgc()BEGINSELECT * FROM TEXT;SELECT * FROM s_user;END//DEL ...

  6. 深圳博客第一篇(Json)

    JSON JSON是纯文本 JSON具有自我描述性 JSON具有层级结构 JSON可通过javascript进行解析 JSON数据可使用Ajax进行传输 JSON对象的取值 var myObj = { ...

  7. [护网杯2018] easy_laravel

    前言 题目环境 buuoj 上的复现,和原版的题目不是完全一样.原题使用的是 nginx + mysql 而 buuoj 上的是 apache + sqlite composer 这是在 PHP5.3 ...

  8. 使用dynamic和MEF实现轻量级的AOP组件 (2)

    转摘 https://www.cnblogs.com/niceWk/archive/2010/07/21/1782092.html 偷梁换柱 上一篇我们初试了DynamicAspect这把小刀,如果你 ...

  9. EF-相关查询(逐渐完善)

    linq查询方式 多条件查询 内连接 左连接 可以执行sql含事务

  10. Golang Web入门(4):如何设计API

    摘要 在之前的几篇文章中,我们从如何实现最简单的HTTP服务器,到如何对路由进行改进,到如何增加中间件.总的来讲,我们已经把Web服务器相关的内容大概梳理了一遍了.在这一篇文章中,我们将从最简单的一个 ...