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. stand up meeting 1-4

    放假归来第一天,组内成员全员到齐,满血复活. 今天主要对下边最后半个月的任务做了规划和分配. UI的优化部分在假期前静雯已经完成在了UI分支上,国庆会在这两天把UI设计的更新merge到master分 ...

  2. stand up meeting 12-4

    今日进步: 1.国庆答题界面和结果界面的连接完成,并能显示GetRankData API返回结果和错误题目的单词信息. 2.天赋: 完成了整个  单词挑战需要碰到的"Storage" ...

  3. A - Oil Deposits DFS

    The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSu ...

  4. Zipper 杭电 1501

    Given three strings, you are to determine whether the third string can be formed by combining the ch ...

  5. fashion_mnist多分类训练,两种模型的保存与加载

    from tensorflow.python.keras.preprocessing.image import load_img,img_to_array from tensorflow.python ...

  6. 使用JAVA API编程实现简易Habse操作

    使用JAVA API编程实现下面内容: 1.创建<王者荣耀>游戏玩家信息表gamer,包含列族personalInfo(个人信息).recordInfo(战绩信息).assetsInfo( ...

  7. <algorithm>中sort()函数的用法

    先说一下,本篇文章我没有讲sort()实现排序的原理,我写在另一篇文章中了,如果想了解的话,可以看一下,附上链接:https://www.cnblogs.com/buanxu/p/12772700.h ...

  8. JS在线代码编辑器多种方案monaco-editor,vue-monaco-editor

    前言 JavaScript在线代码编辑器. 需要代码提示,关键字高亮,能够格式化代码.(不需要在线运行) 简简单单的需求. 方案一: Monaco-editor 简介:微软的开源项目,开源中国上面的在 ...

  9. 2019-2020-1 20199328《Linux内核原理与分析》第二周作业

    冯诺依曼体系结构的核心是: 冯诺依曼体系结构五大部分:控制器,运算器,存储器,输入输出设备. 常用的寄存器 AX.BX.CX.DX一般存放一些一般的数据,被称为通用寄存器,分别拥有高8位和低8位. 段 ...

  10. centos7.4安装docker

    安装docker的前提条件 1)关闭系统的防火墙和selinux 2)  同步系统时间 3)系统必须是centos7以上 移除旧版本yum remove docker docker-client do ...