A. Altitude

从小到大加入每个数,用set查找前驱和后继即可。

时间复杂度$O(n\log n)$。

#include <bits/stdc++.h>
using namespace std ;
const int Maxn=100020,Inf=1e9;
typedef pair<int,int>pi;
int n;
int a[Maxn];
vector<pi>V;
set<int>S;
int ans,rep1,rep2,rep3;
int caldis(int x,int y){
return y>x?(y-x):(y+n-x);
}
void ask(int loc){
if(!S.size())return ;
set<int>::iterator it=S.lower_bound(loc);
set<int>::iterator it2=it;
for(int i=0;i<2;i++){
if(it2==S.begin()){it2=S.end();it2--;}
else it2--;
}
int ret1=Inf,ret2=Inf,cs1,cs2;
for(int i=0;i<5;i++){
int t1=caldis(*it2,loc);
int t2=caldis(loc,*it2);
if(t1<ret1){cs1=*it2;ret1=t1;}
if(t2<ret2){cs2=*it2;ret2=t2;}
it2++;
if(it2==S.end())it2=S.begin();
}
if(ret1+ret2<ans){rep1=cs1;rep2=loc;rep3=cs2;ans=ret1+ret2;}
return ;
}
int main () {
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",a+i),V.push_back(pi(a[i],i));
sort(V.begin(),V.end());
ans=Inf;
for(int i=0,j;i<V.size();i=j){
for(j=i;j<V.size();j++){
if(V[j].first!=V[i].first)break;
ask(V[j].second);
}
for(int k=i;k<j;k++){
S.insert(V[k].second);
}
}
printf("%d %d %d\n",rep1,rep2,rep3);
return 0 ;
}

  

B. Blocking Buffer

观察发现$\gcd(r,w)$都是可以达到的,于是欧几里得求一下即可。

#include <bits/stdc++.h>
using namespace std ;
const int Maxn=200020,Inf=1e9;
typedef pair<int,int>pi;
typedef long long LL;
bool solve(LL l,LL A,LL B){
if(l-B>=A-1)return 0;
LL gc=__gcd(A,B);
LL tmp=(l-B)/gc*gc;
while(tmp<=l-B)tmp+=gc;
if(tmp<A)return 1;
return 0;
}
int main () {
LL l,A,B;
while(cin>>l>>A>>B){
/*
set<LL>S;
LL cur=0;
bool flag=1;
S.insert(0);
while(1){
if(cur>l-B&&cur<A){
flag=0;
break;
}
if(cur>=A){
cur%=A;
}
else{
cur=(l-cur)/B*B+cur;
}
if(S.find(cur)!=S.end()){break;}
}
puts(flag?"OK":"DEADLOCK");
*/
puts(solve(l,A,B)?"DEADLOCK":"OK");
}
return 0 ;
}

  

C. Catch Me If You Can

留坑。

D. Demolition Time

留坑。

E. Economy Printing

将数字从小到大排序,那么第$i$个数要么自己作为开头,要么和$i-2$连接,要么和$i-1$连接,设$f[i][j][k]$表示考虑了前$i$个数,第$i-1$个数用操作$j$,第$i$个数用操作$k$时的最小串长,然后DP即可。

时间复杂度$O(n\log n)$。

#include <bits/stdc++.h>
using namespace std ; typedef pair < int , int > pii ; #define clr( a , x ) memset ( a , x, sizeof a ) const int MAXN = 200005 ;
const int INF = 0x3f3f3f3f ;
int n ; int len[MAXN] ;
int a[MAXN] ;
int dp[MAXN][4][4] ;
int f[MAXN] ;
pii p[MAXN][4][4] ;
int vis[MAXN] ; int calc ( int x ) {
int t = 0 ;
while ( x ) {
t ++ ;
x /= 10 ;
}
return t ;
} void dfs ( int n , int x , int y ) {
if ( n == 1 ) return ;
int nx = p[n][x][y].first ;
int ny = x ;
f[n] = p[n][x][y].second ;
dfs ( n - 1 , nx , ny ) ;
} int dfs2 ( int x ) {
vis[x] = 1 ;
if ( f[x] == 0 ) return x ;
return dfs2 ( f[x] ) ;
} void solve () {
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d" , &a[i] ) ;
}
sort ( a + 1 , a + n + 1 ) ;
for ( int i = 1 ; i <= n ; ++ i ) {
len[i] = calc ( a[i] ) ;
}
clr ( f , 0 ) ;
clr ( p , 0 ) ;
clr ( dp , INF ) ;
dp[0][0][0] = 0 ;
for ( int i = 1 ; i <= n ; ++ i ) {
for ( int j = 0 ; j < 4 ; ++ j ) {
for ( int k = 0 ; k < 4 ; ++ k ) if ( dp[i - 1][j][k] != INF ) {
for ( int l = 0 ; l < 4 ; ++ l ) {
int tmp = dp[i - 1][j][k] + 1 + len[i] ;
if ( l ) tmp = tmp + 1 + len[i] ;
if ( l == 1 && a[i] % 2 == 0 ) continue ;
if ( l == 2 && a[i] % 2 == 1 ) continue ;
if ( dp[i][k][l] > tmp ) {
dp[i][k][l] = tmp ;
p[i][k][l] = pii ( j , 0 ) ;
}
}
if ( j == 1 || j == 2 ) {
if ( i > 2 && a[i] - a[i - 2] == 2 ) {
int tmp = dp[i - 1][j][k] + len[i] - len[i - 2] ;
if ( dp[i][k][j] > tmp ) {
dp[i][k][j] = tmp ;
p[i][k][j] = pii ( j , i - 2 ) ;
}
}
}
if ( k == 1 || k == 2 ) {
if ( i > 1 && a[i] - a[i - 1] == 2 ) {
int tmp = dp[i - 1][j][k] + len[i] - len[i - 1] ;
if ( dp[i][k][k] > tmp ) {
dp[i][k][k] = tmp ;
p[i][k][k] = pii ( j , i - 1 ) ;
}
}
}
if ( k == 3 ) {
if ( i > 1 && a[i] - a[i - 1] == 1 ) {
int tmp = dp[i - 1][j][k] + len[i] - len[i - 1] ;
if ( dp[i][k][k] > tmp ) {
dp[i][k][k] = tmp ;
p[i][k][k] = pii ( j , i - 1 ) ;
}
}
}
}
}
}
int ans = INF , x = -1 , y = -1 ;
for ( int i = 0 ; i < 4 ; ++ i ) {
for ( int j = 0 ; j < 4 ; ++ j ) {
if ( dp[n][i][j] < ans ) {
ans = dp[n][i][j] ;
x = i ;
y = j ;
}
}
}
dfs ( n , x , y ) ;
//printf ( "%d\n" , ans - 1 ) ;
clr ( vis , 0 ) ;
int flag = 0 ;
for ( int i = n ; i >= 1 ; -- i ) if ( !vis[i] ) {
int L = dfs2 ( i ) ;
if ( flag ) putchar ( ',' ) ;
flag = 1 ;
if ( L == i ) printf ( "%d" , a[i] ) ;
else {
printf ( "%d" , a[L] ) ;
if ( a[i] - a[f[i]] == 2 ) {
if ( a[i] % 2 == 0 ) putchar ( '%' ) ;
else putchar ( '#' ) ;
} else putchar ( '-' ) ;
printf ( "%d" , a[i] ) ;
}
}
puts ( "" ) ;
} int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}

  

F. Format

枚举有没有"^"符号,然后将字符分成三类:可选可不选、必须要选、必须不能选。

设$f[i]$表示处理完字典序最小的$i$个字符时的最短串长以及对应串长的字典序最小串,然后枚举往前延伸到哪里转移。

需要注意的是,如果全部字符都出现了,那么答案应该是%[^!],需要特判。

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;
typedef pair<int,string>P;
const int N=300;
int n,i,j,v[N];char s[222222];
P ans(N,""),f[N];
inline bool check(char x){
if(x==' ')return 1;
if(x>='0'&&x<='9')return 1;
if(x>='a'&&x<='z')return 1;
if(x>='A'&&x<='Z')return 1;
return 0;
}
void dp(){
for(i=32;i<=126;i++){
f[i]=P(N,"");
if(v[i]==0||v[i]==2){
P t=f[i-1];
f[i]=t;
}
if(v[i]==0||v[i]==1){
for(j=i;j>=32;j--){
if(v[j]==2)break;
P t=f[j-1];
if(j==i){
t.first++;
t.second.push_back(char(i));
}else if(j+1==i){
t.first+=2;
t.second.push_back(char(j));
t.second.push_back(char(i));
}else{
t.first+=3;
t.second.push_back(char(j));
t.second+="-";
t.second.push_back(char(i));
}
f[i]=min(f[i],t);
}
}
}
}
int main(){
fgets(s,111111,stdin);
n=strlen(s);
//0 : can choose and can not choose
//1 : must choose
//2 : mustn't choose
for(i=32;i<=126;i++)v[i]=0;
for(i=0;i<n;i++)if(check(s[i]))v[s[i]]=1;
for(i=32;i<=126;i++)if(!v[i]&&check(i))v[i]=2;
f[31]=P(0,"%[");
dp();
ans=f[126];
for(i=32;i<=126;i++)v[i]=0;
for(i=0;i<n;i++)if(check(s[i]))v[s[i]]=2;
for(i=32;i<=126;i++)if(!v[i]&&check(i))v[i]=1;
f[31]=P(1,"%[^");
dp();
if(f[126].first>1)ans=min(ans,f[126]);else ans=min(ans,P(2,"%[^!"));
ans.second+="]";
cout<<ans.second<<endl;
return 0;
}

  

G. Great Guest Gathering

分成$n$轮构造即可。

#include <bits/stdc++.h>
using namespace std ; int n ; void solve () {
printf ( "%d %d %d\n" , 1 , 1 , 0 ) ;
for ( int i = 1 ; i < n ; ++ i ) {
for ( int j = i + 2 ; j <= n ; ++ j ) {
printf ( "%d %d %d\n" , j , j , i ) ;
printf ( "%d %d %d\n" , i , i , j ) ;
}
printf ( "%d %d %d\n" , i + 1 , i + 1 , i ) ;
}
for ( int i = n - 1 ; i >= 2 ; -- i ) {
printf ( "%d %d %d\n" , i , i , i + 1 ) ;
}
printf ( "%d %d %d\n" , 0 , 1 , 2 ) ;
} int main () {
while ( ~scanf ( "%d" , &n ) ) solve () ;
return 0 ;
}

  

H. Hockey Cup

按题意模拟即可。

#include <bits/stdc++.h>
using namespace std ;
const int Maxn=200020,Inf=1e9;
typedef pair<int,int>pi;
typedef long long LL;
map<string,int>Mp; string ts[]={"Russia","Sweden","Finland","NA"};
int res[4][4][3];
int sc[4][6];
int g[4][4];
int cmpop;
bool cmp(int a,int b){
return sc[a][cmpop]>sc[b][cmpop];
}
void solve(vector<int>&v,int ty){
if(v.size()<=2){
if(v.size()==1)return ;
if(v.size()==2){
if(!g[v[0]][v[1]])swap(v[0],v[1]);
}
return ;
}
cmpop=ty;
sort(v.begin(),v.end(),cmp);
vector<int>rv;
for(int i=0,j;i<v.size();i=j){
vector<int>tmp;
for(j=i;j<v.size();j++){
if(sc[v[j]][ty]!=sc[v[i]][ty]){break;}
tmp.push_back(v[j]);
}
solve(tmp,ty+1);
for(int it=0;it<tmp.size();it++)rv.push_back(tmp[it]);
}
swap(rv,v);
}
int go(){
vector<int>v;
for(int i=0;i<4;i++)v.push_back(i);
solve(v,0);
if(!v[0]||!v[1])return 1<<1;
return 1<<0;
}
int check(){
memset(sc,0,sizeof sc);
int ret=0;
for(int i=0;i<4;i++){
for(int j=i+1;j<4;j++){
int t1=res[i][j][0],t2=res[i][j][1];
int t3=res[i][j][2];
int ti=i,tj=j;
g[i][j]=1;g[j][i]=0;
if(t1<t2){
g[i][j]=0;g[j][i]=1;
swap(ti,tj);
swap(t1,t2);
}
sc[ti][0]+=2;
sc[ti][1]++;
if(!t3)sc[ti][2]++;
sc[ti][3]+=t1-t2;
sc[ti][4]+=t1;
if(t3)sc[tj][0]++;
sc[tj][3]-=t1-t2;
sc[tj][4]+=t2;
}
}
int tmp[10];
for(int i=0;i<4;i++)tmp[i]=i;
do{
for(int i=0;i<4;i++)sc[i][5]=tmp[i];
ret|=go();
}while(next_permutation(tmp,tmp+4));
return ret;
}
int main () {
for(int i=0;i<4;i++)Mp[ts[i]]=i;
string name1,name2;
for(int i=0;i<5;i++){
string name1,name2;
char ss[10];
int t1,t2,t3;
cin>>name1>>name2>>t1>>t2;
fgets(ss,sizeof ss,stdin);
if(strlen(ss)>=2){
t3=1;
}
else t3=0;
int id1=Mp[name1],id2=Mp[name2];
if(id1>id2){swap(t1,t2);swap(id1,id2);}
res[id1][id2][0]=t1;
res[id1][id2][1]=t2;
res[id1][id2][2]=t3;
}
cin>>name1>>name2;
int id1=Mp[name1],id2=Mp[name2];
int ans=0;
if(id1>id2)swap(id1,id2);
for(int i=0;i<100;i++){
for(int j=0;j<100;j++){
if(i==j)continue;
res[id1][id2][0]=i;
res[id1][id2][1]=j;
res[id1][id2][2]=0;
ans|=check();
if(abs(i-j)==1){
res[id1][id2][2]=1;
ans|=check();
}
}
}
if(ans==3)puts("Believe in playoff!");
else if(ans==2)puts("Already in playoff!");
else puts("No chance");
return 0 ;
}

  

I. Interesting Interactive Idea

留坑。

J. Juice Degustation

留坑。

K. Knights of the Old Republic

考虑对图做集合DP,设$f[S]$表示占领S集合的最小代价,考虑从小到大加入每条边,加入每条边时,如果形成环,那么显然可以扔掉。

否则$f[S]=\min(f[A]+f[B],\min(A中费用最小的点,B中费用最小的点)\times\max(A中需求最大的点,B中需求最大的点,当前边权))$。

在Kruskal的时候用并查集维护即可。

时间复杂度$O(m\log m)$。

#include <bits/stdc++.h>
using namespace std ; typedef long long LL ; const int MAXN = 300005 ; struct Edge {
int u , v , c ;
bool operator < ( const Edge& a ) const {
return c < a.c ;
}
} ; Edge E[MAXN] ;
int a[MAXN] , b[MAXN] , p[MAXN] ;
LL sum[MAXN] ;
int n , m ; int F ( int x ) {
return p[x] == x ? x : ( p[x] = F ( p[x] ) ) ;
} void solve () {
for ( int i = 1 ; i <= n ; ++ i ) {
p[i] = i ;
}
for ( int i = 1 ; i <= n ; ++ i ) {
scanf ( "%d%d" , &a[i] , &b[i] ) ;
sum[i] = 1LL * a[i] * b[i] ;
}
for ( int i = 0 ; i < m ; ++ i ) {
scanf ( "%d%d%d" , &E[i].u , &E[i].v , &E[i].c ) ;
}
sort ( E , E + m ) ;
for ( int i = 0 ; i < m ; ++ i ) {
int x = F ( E[i].u ) ;
int y = F ( E[i].v ) ;
if ( x == y ) continue ;
int na = max ( max ( a[x] , a[y] ) , E[i].c ) ;
int nb = min ( b[x] , b[y] ) ;
LL tmp = 1LL * na * nb ;
sum[y] = min ( sum[x] + sum[y] , tmp ) ;
p[x] = y ;
a[y] = na ;
b[y] = nb ;
}
LL ans = 0 ;
for ( int i = 1 ; i <= n ; ++ i ) {
if ( F ( i ) == i ) ans += sum[i] ;
}
printf ( "%lld\n" , ans ) ;
} int main () {
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}

  

L. Lazy Coordinator

从后往前处理,维护当前时刻到每个时刻被选用的概率乘以时刻之和,减去当前出题人报名的时间即可。

时间复杂度$O(n)$。

#include <bits/stdc++.h>
using namespace std ;
const int Maxn=200020,Inf=1e9;
typedef pair<int,int>pi;
int n;
int arr[Maxn];
char op[Maxn];
int tl[Maxn],has[Maxn],idx[Maxn];
double ans[Maxn];
int main () {
scanf("%d",&n);
int cnt=0,id=0;
for(int i=1;i<=n*2;i++){
scanf(" %c%d",&op[i],&tl[i]);
idx[i]=-1;
if(op[i]=='+'){
id++;
arr[id]=tl[i];
idx[i]=id;
cnt++;
}
else{
cnt--;
}
has[i]=cnt;
}
double sum=0;
for(int i=n*2;i>=1;i--){
if(op[i]=='-'){
int k=has[i]+1;
sum=sum*(1.0-1.0/k)+tl[i]*(1.0/k);
}
else ans[idx[i]]=sum;
}
for(int i=1;i<=n;i++)printf("%.12f\n",ans[i]-arr[i]);
return 0 ;
}

  


总结:

  • E题思考方向错了,在错误的道路上越走越远,以致最后半小时想出正解却没有时间写完。
  • G题poursoul没过样例就自信提交,导致在样例WA,下次要注意。

2016-2017 ACM-ICPC, NEERC, Moscow Subregional Contest的更多相关文章

  1. 2016 NEERC, Moscow Subregional Contest K. Knights of the Old Republic(Kruskal思想)

    2016 NEERC, Moscow Subregional Contest K. Knights of the Old Republic 题意:有一张图,第i个点被占领需要ai个兵,而每个兵传送至该 ...

  2. 2018-2019 ICPC, NEERC, Southern Subregional Contest

    目录 2018-2019 ICPC, NEERC, Southern Subregional Contest (Codeforces 1070) A.Find a Number(BFS) C.Clou ...

  3. Codeforces 2018-2019 ICPC, NEERC, Southern Subregional Contest

    2018-2019 ICPC, NEERC, Southern Subregional Contest 闲谈: 被操哥和男神带飞的一场ACM,第一把做了这么多题,荣幸成为7题队,虽然比赛的时候频频出锅 ...

  4. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 G. Garden Gathering

    Problem G. Garden Gathering Input file: standard input Output file: standard output Time limit: 3 se ...

  5. ACM ICPC 2015 Moscow Subregional Russia, Moscow, Dolgoprudny, October, 18, 2015 D. Delay Time

    Problem D. Delay Time Input file: standard input Output file: standard output Time limit: 1 second M ...

  6. 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror) Solution

    从这里开始 题目列表 瞎扯 Problem A Find a Number Problem B Berkomnadzor Problem C Cloud Computing Problem D Gar ...

  7. 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem D. Distance 迪杰斯特拉

    Problem D. Distance 题目连接: http://codeforces.com/gym/100714 Description In a large city a cellular ne ...

  8. 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem C. Contest 水题

    Problem C. Contest 题目连接: http://codeforces.com/gym/100714 Description The second round of the annual ...

  9. 2016-2017 ACM-ICPC, NEERC, Moscow Subregional Contest Problem L. Lazy Coordinator

    题目来源:http://codeforces.com/group/aUVPeyEnI2/contest/229511 时间限制:1s 空间限制:512MB 题目大意: 给定一个n 随后跟着2n行输入 ...

  10. Codeforces1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)总结

    第一次打ACM比赛,和yyf两个人一起搞事情 感觉被两个学长队暴打的好惨啊 然后我一直做傻子题,yyf一直在切神仙题 然后放一波题解(部分) A. Find a Number LINK 题目大意 给你 ...

随机推荐

  1. 用U盘安装系统的好用的PE系统:通用PE V6.1下载

    用U盘安装系统的好用的PE系统:通用PE V6.1下载 PE是一款用其他介质(我们最常用的是U盘)启动安装电脑系统的简易操作系统,在XP系统中 最经典的是扬州老毛桃出品的只有100多兆的XP内核的PE ...

  2. 安卓log4k问题解决

    1.直接上代码 //log4k问题 public static void log(String tag, String str) { int index = 0; // 当前位置 int max = ...

  3. Interop with Native Libraries

    http://www.mono-project.com/docs/advanced/pinvoke/

  4. [Java] JSP笔记 - Java Bean

    一. Java Bean 是什么? Java Bean 其实就是一个符合特定规则的 Java Class.这些规则包括: 使用 public 声明的公用类 属性使用public 的get,set方法访 ...

  5. 将javascript函数写在Html标签里

    有些时候不想把函数写在script标签里了,想直接在html标签里直接加上js代码,可以这样写: <body onload="javascript:{window.location.h ...

  6. [NHibernate]并发控制

    目录 写在前面 文档与系列文章 并发控制 乐观并发控制(Optimistic Concurrency) 一个例子 悲观并发控制(Pessimistic Concurrency) 总结 写在前面 上篇文 ...

  7. Android锁屏后数据改变的解决方案

    如果一个界面设置成横屏,那么锁屏再开启之后,会重新执行一遍onCreate()方法.对于这个问题的解决方案如下: 只需要在Menifest文件的activity相应标签下添加这行代码即可: andro ...

  8. [Python] 学习笔记之MySQL数据库操作

    1 Python标准数据库接口DB-API介绍 Python标准数据库接口为 Python DB-API,它为开发人员提供了数据库应用编程接口.Python DB-API支持很多种的数据库,你可以选择 ...

  9. magic_quotes_gpc和magic_quotes_runtime的区别和用法详解

    当你的数据中有一些     "  ' 这样的字符要写入到数据库里面,又想不被过滤掉的时候,它就很有用,会在这些字符前自动加上,如 中国地大物博"哈哈" 中国\地大物博&q ...

  10. saltstack-部署

    安装epel源(所有主机安装) [root@salt-server /]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/r ...