Gym101986: Asia Tsukuba Regional Contest(寒假自训第12场)
A .Secret of Chocolate Poles
题意:有黑白两种木块,黑色有1,K两种长度; 白色只有1一种长度,问满足黑白黑...白黑形式,长度为L的组合种类。
思路:直接DP即可。
- #include<bits/stdc++.h>
- #define ll long long
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- ll dp[][],ans;
- int main()
- {
- int L,K;
- scanf("%d%d",&L,&K);
- dp[][]=;
- rep(i,,L){
- dp[i][]=dp[i-][];
- dp[i][]=dp[i-][];
- if(i-K>=) dp[i][]+=dp[i-K][];
- }
- rep(i,,L) ans+=dp[i][];
- printf("%lld\n",ans);
- return ;
- }
B .Parallel Lines
题意:给定二维平面上N个点,N是偶数,限制让你两两连线,使得平行线对数最多。N<=16;
思路:N为16时,复杂度=15*13*11*9*7*5*3*1~=2e6;所以可以枚举所有情况,即搜索可以做。 注意是两两配对,没有不选的情况,不然复杂度很高。
统计时用了map带了个log。 这个log还可以优化掉,比如,变为每次加入一个斜率x时,res+=num[x]; num[x]++; 就不用map记录每个斜率的个数,最后才去统计答案了。
- #include<bits/stdc++.h>
- #define ll long long
- #define pii pair<int,int>
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- int X[maxn],Y[maxn],ans,N,vis[maxn];
- map<pii,int>mp; map<pii,int>::iterator it;
- pii a[maxn][maxn];
- void dfs(int pos)
- {
- if(pos==N+){
- int res=;
- for(it=mp.begin();it!=mp.end();it++){
- res+=(it->second)*((it->second)-)/;
- }
- ans=max(ans,res);
- return ;
- }
- if(!vis[pos])
- for(int i=pos+;i<=N;i++){
- if(!vis[i]){
- vis[i]=;
- mp[a[pos][i]]++;
- dfs(pos+);
- mp[a[pos][i]]--;
- vis[i]=;
- }
- }
- else dfs(pos+);
- }
- int main()
- {
- scanf("%d",&N);
- rep(i,,N) scanf("%d%d",&X[i],&Y[i]);
- rep(i,,N) rep(j,i+,N){
- int dx=X[j]-X[i],dy=Y[j]-Y[i];
- if(dx<) dx=-dx,dy=-dy;
- if(dx==) dy=abs(dy);
- int g=__gcd(dx,dy);
- dx/=g; dy/=g;
- a[i][j]=pii(dx,dy);
- }
- dfs();
- printf("%d\n",ans);
- return ;
- }
C .Medical Checkup
题意:有有无限个医院,N个学生,第i个学生在每个医院检查的时间都一样,是hi。 他们排成一队去检查。 满足,一个医院不能同时检查多个人,一个人前面的那个人检查完后才能去检查, 给定时间T,问每个人在哪个医院里检查(或者在等候)。
思路:对思维题不感冒啊,想的过于复杂了。 这个题,对于所有的人都满足的东西是开始入队的时间是一定的,即h1+h2+...hi-1。
然后,从他开始检查开始,就把入队的看成一个整体,那么,这个整体的队尾前进的距离,取决于整个队伍前进的最小距离。
所以不难得出他们的答案=(T-h1-h2-...)/hi+2;
- #include<bits/stdc++.h>
- #define ll long long
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- ll h[maxn];
- int main()
- {
- int N; ll sum=,T,Mx=;
- scanf("%d%lld",&N,&T);
- rep(i,,N){
- scanf("%lld",&h[i]);
- Mx=max(Mx,h[i]);
- sum+=h[i];
- if(T>=sum) printf("%lld\n",(T-sum )/Mx+);
- else printf("1\n");
- }
- return ;
- }
E .Black or White
题意:给定一排,N个砖,只有黑白两色,给出它们初始的颜色S,限制你有长度为1到K的刷子,问至少刷多少次,可以把它们刷成给定状态T。
思路:假设一排长度为M的没有颜色砖,染色成BWBWBW..的形式,至少需要(M+1)/2+1刷子。 所以其实初始状态没有多大用处(除非相同),我们只考虑目标状态。
我们把T种相邻颜色相同的看成一个整体,那么:
dp[i]=dp[i-1]; 当s[i]==t[i];
dp[i]=dp[j]+(sum[i]-sum[j+1]+1)/2+1; 当s[i]!=t[i];
第二个方程直接单调队列可以搞。 如果我们考虑了初始状态,那么只会越想越复杂。
- #include<bits/stdc++.h>
- #define rep(i,w,v) for(int i=w;i<=v;i++)
- using namespace std;
- const int maxn=;
- int dp[maxn],sum[maxn],q[maxn],head,tail,N,K;
- char a[maxn],b[maxn];
- int main()
- {
- scanf("%d%d",&N,&K);
- scanf("%s%s",a+,b+);
- rep(i,,N) sum[i]=sum[i-]+(b[i]!=b[i-]);
- head=tail=; q[]=;
- rep(i,,N){
- if(a[i]==b[i]) dp[i]=dp[i-];
- else
- dp[i]=dp[q[head]]+(sum[i]-sum[q[head]+]+)/+;
- while(tail>=head&&dp[i]*-sum[i+]<=dp[q[tail]]*-sum[q[tail]+]) tail--;
- while(tail>=head&&i-q[head]>=K) head++;
- q[++tail]=i;
- }
- printf("%d\n",dp[N]);
- return ;
- }
I .Starting a Scenic Railroad Service
题意:给定N个人的陆游线路,问自己选票的情况下,和售票方选票的情况下,旅游车需要多少个位置。
思路:反正题意差不多是这样,第一个问是问max(一个人的路线+和他规范相交的路线个数)。 第二个问是max(单点最大路线覆盖);
第二个问,由于数据小,可以用差分或者线段树; 如果数据大,可以直接排序做。 是个常规题了。
第一个问,和一个线段相交的线段个数,=N-在他前面的-在他后面的。 不难想到也可以差分去做。 数据大后还是可以排序来做。
覆盖问题,个人更喜欢写排序,因为不用考虑下标大小,或者离散化导致的边界问题。
- #include<bits/stdc++.h>
- #define ll long long
- #define pii pair<int,int>
- #define f first
- #define s second
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- pii a[maxn],b[maxn];
- int A[maxn],B[maxn],ans1,ans2,tot;
- int main()
- {
- int N,pre=; scanf("%d",&N);
- rep(i,,N) {
- scanf("%d%d",&a[i].f,&a[i].s);
- b[++tot]=pii(a[i].f,);
- b[++tot]=pii(a[i].s,-);
- }
- rep(i,,N){
- A[a[i].f]++;
- B[a[i].s]++;
- }
- rep(i,,) A[i]+=A[i-],B[i]+=B[i-];
- rep(i,,N){
- int f=B[a[i].f]+N-A[a[i].s-];
- ans1=max(ans1,N-f);
- }
- sort(b+,b+tot+);
- rep(i,,tot){
- if(b[i].s==-) pre--;
- else pre++;
- ans2=max(ans2,pre);
- }
- printf("%d %d\n",ans1,ans2);
- return ;
- }
F .Pizza Delivery
题意:给定N点M边有向带权图,起点S=1,终点T=2; 对于每个边,问他转向后,起点到终点的最短路变大还是变小或者不变。
思路:首先肯定要两次SPFA,求出S和T到每个点的最短路,分别是dis1,dis2;
当且仅当,然后如果dis1[v]+dis2[u]+w[i]<dis1[T],那么这条边可以让最短路变小。
否则,最短路变大或者不变,如果不变,说明最短路不是必经这条边。
那么本题的关键问题就是问边是否是最短路必经边。
我们把最短路上的边抽出来(就是满足dis1[u]+dis2[v]+w[i]==dis1[T]那些有向边,把它看成无向边),然后不难想到就是求“桥”。
如果桥转向了,那么最短路一定变长。
- #include<bits/stdc++.h>
- #define ll long long
- #define rep(i,a,b) for(int i=a;i<=b;i++)
- using namespace std;
- const int maxn=;
- const ll inf=1LL<<;
- struct dijst
- {
- struct in{
- ll dis;int u;
- in(){}
- in(ll d,int uu):dis(d),u(uu){}
- bool friend operator<(in w,in v){
- return w.dis>v.dis;
- }
- };
- ll dis[maxn]; int Len[maxn],cnt,S;
- int Laxt[maxn],Next[maxn],inq[maxn],To[maxn];
- void init(int N){
- cnt=; rep(i,,N) inq[i]=Laxt[i]=,dis[i]=inf;
- }
- void add(int u,int v,int w){
- Next[++cnt]=Laxt[u]; Laxt[u]=cnt;
- To[cnt]=v; Len[cnt]=w;
- }
- void SPFA()
- {
- dis[S]=; priority_queue<in>q;
- q.push(in(0LL,S));
- while(!q.empty())
- {
- int u=q.top().u; q.pop(); inq[u]=;
- for(int i=Laxt[u];i;i=Next[i]){
- int v=To[i];
- if(dis[v]>dis[u]+Len[i]){
- dis[v]=dis[u]+Len[i];
- if(!inq[v]) inq[v]=,q.push(in(dis[v],v));
- }
- }
- }
- }
- }D1,D2;
- int a[maxn],b[maxn],c[maxn],cnt;
- int dfn[maxn],low[maxn],times,Br[maxn];
- int Laxt[maxn],Next[maxn],To[maxn],id[maxn];
- void add(int u,int v,int p)
- {
- Next[++cnt]=Laxt[u]; Laxt[u]=cnt;
- To[cnt]=v; id[cnt]=p;
- }
- void tarjan(int u,int fa)
- {
- dfn[u]=low[u]=++times;
- for(int i=Laxt[u];i;i=Next[i]){
- int v=To[i];
- if(!dfn[v]){
- tarjan(v,u);
- low[u]=min(low[u],low[v]);
- if(low[v]>dfn[u]) Br[id[i]]=;
- }
- else if(v!=fa) low[u]=min(low[u],dfn[v]);
- }
- }
- int main()
- {
- int N,M;
- scanf("%d%d",&N,&M);
- D1.init(N); D2.init(N);
- D1.S=; D2.S=;
- rep(i,,M) {
- scanf("%d%d%d",&a[i],&b[i],&c[i]);
- D1.add(a[i],b[i],c[i]);
- D2.add(b[i],a[i],c[i]);
- }
- D1.SPFA(); D2.SPFA(); ll Dis=D1.dis[];
- rep(i,,M){
- if(D1.dis[a[i]]+D2.dis[b[i]]+c[i]==Dis){
- add(a[i],b[i],i);
- add(b[i],a[i],i);
- }
- }
- rep(i,,N) if(!dfn[i]) tarjan(i,);
- rep(i,,M){
- if(D1.dis[b[i]]+D2.dis[a[i]]+c[i]<Dis) printf("HAPPY\n");
- else if(Br[i]) printf("SAD\n");
- else printf("SOSO\n");
- }
- return ;
- }
Gym101986: Asia Tsukuba Regional Contest(寒假自训第12场)的更多相关文章
- Gym.101955: Asia Shenyang Regional Contest(寒假自训第10场)
C.Insertion Sort 题意:Q次询问,每次给出N,M,Mod,问你有多少种排列,满足前面M个数字排序之后整个序列的LIS>=N-1. 思路:我们把数字看成[1,M],[N-M+1,N ...
- Gym102040 .Asia Dhaka Regional Contest(寒假自训第9场)
B .Counting Inversion 题意:给定L,R,求这个区间的逆序对数之和.(L,R<1e15) 思路:一看这个范围就知道是数位DP. 只是维护的东西稍微多一点,需要记录后面的各种数 ...
- 2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest
2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest A Secret of Chocolate Poles 思路:暴力枚举黑巧克力的个数和厚黑巧克力的个 ...
- 2016-2017 ACM-ICPC, Asia Tsukuba Regional Contest D Hidden Anagrams
题目链接:http://codeforces.com/gym/101158/attachments /* * @Author: lyucheng * @Date: 2017-10-21 12:20:0 ...
- (好题)2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest F Pizza Delivery
题意:给n个点m条边的有向图.每次使一条边反向,问你1到2的最短路变短,变长,还是不变. 解法:遇到这种题容易想到正向求一遍最短路d1,反向再求一遍最短路d2.纪录原图上的最短路为ans,然后分开考虑 ...
- 2017-2018 ACM-ICPC, Asia Tsukuba Regional Contest E:Black or White
这道题可以比较容易看出是线性DP.设dp[i]代表把前i个格子刷成目标状态的最小步数. 写出状态转移方程 dp[i]=min( dp[j]+calc(j+1,i) ) (i-j<=k) calc ...
- Gym.102006:Syrian Collegiate Programming Contest(寒假自训第11场)
学习了“叙利亚”这个单词:比较温和的一场:几何的板子eps太小了,坑了几发. A .Hello SCPC 2018! 题意:给定一个排列,问它是否满足,前面4个是有序的,而且前面4个比后面的都小. 思 ...
- Gym.101908 Brazil Subregional Programming Contest(寒假自训第六场)
这几天睡眠时间都不太够,室友晚上太会折腾了,感觉有点累,所以昨天的题解也没写,看晚上能不能补起来. B . Marbles 题意:给定N组数(xi,yi),玩家轮流操作,每次玩家可以选择其中一组对其操 ...
- zoj 3659 Conquer a New Region The 2012 ACM-ICPC Asia Changchun Regional Contest
Conquer a New Region Time Limit: 5 Seconds Memory Limit: 32768 KB The wheel of the history roll ...
随机推荐
- 一篇文章有若干行,以空行作为输入结束的条件。统计一篇文章中单词the(不管大小写,单词the是由空格隔开的)的个数。
#include <iostream>using namespace std; int k = 0;int n = 0;int main() { char c; char a[1000]; ...
- git Please move or remove them before you can merge.
git clean -d -fx "" 其中 x -----删除忽略文件已经对git来说不识别的文件 d -----删除未被添加到git的路径中的文件 f -----强制运行
- asp.netmvc 三层搭建一个完整的项目
接下来用 asp.net mvc 三层搭建一个完整的项目: 架构图: 使用的数据库: 一张公司的员工信息表,测试数据 解决方案项目设计: 1.新建一个空白解决方案名称为Company 2.在该解决方案 ...
- Java冒泡排序与选择排序
Java排序: 一.冒泡排序算法的运作如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. ...
- flask项目结构(五)使用数据库
简介: 基础搭建好了,开始读写数据库吧.毕竟写的程序,也没什么高深的,就是CRUD,中文说是增删改查. 一:在数据库中增加测试数据. 在项目根目录建立init_test.py from config ...
- sas 变量类型转换
data b2: set b1; newbl=put(oldbl,10.); run; 根据转换后的类型灵活填写
- python中的argparse模块(参数解析)
import argparseparse = argparse.ArgumentParser()parse.add_argument("a", help="params ...
- 在嵌入式设计中使用MicroBlaze(Vivado版本)(转)
原文Xilinx官方文档<ug898-vivado-embedded-design>第三章 一.MicroBlaze处理器设计介绍(略) 二.创建带有MicroBlaze处理器的IP设计 ...
- 关于Java课堂实验中的一些总结(Scanner)
import java.util.Scanner; 这个头文件是java里面用来输入东西的,就相当于c++里面的iostream输入流...?暂且这么理解吧 然后使用方法:Scanner in = n ...
- MPX
Pre-processing: MPX使用的滤波器是自适应性的‘Wiener’ filter.有时甚至不用MPX,因为尽管Wiener 所引起的扰乱是可以忽略的,有时发现滤波并不能很好地提高拾取的精度 ...