传送门:

Problem A

温暖的签到题

#include<bits/stdc++.h>
using namespace std;
const int maxn=1007;
char s1[maxn],s2[maxn];
int main(){ios::sync_with_stdio(false);cin.tie(0);int n,k,sum0=0,sum1=0;cin>>k>>s1>>s2;n=strlen(s1);for (int i=0;i<n;i++)if (s1[i]==s2[i]) sum1++;else sum0++;int ans=0;if (k<=sum1) ans=k+sum0;else ans=sum1+sum0-(k-sum1);cout<<ans<<endl;return 0;
}

Problem B

莫比乌斯反演大原题!

BZOJ2301的简化版,在那个题上只需要令k=1k=1k=1

#include <bits/stdc++.h>
using namespace std;
const int maxn=10000007;
bool check[maxn+10];
int prime[maxn+10];
int mu[maxn+10];
typedef long long ll;
void Moblus(){for(int i=0;i<=maxn;i++){check[i]=false;}mu[1]=1;int tot=0;for(int i=2;i<=maxn;i++){if(!check[i]){prime[tot++]=i;mu[i]=-1;}for(int j=0;j<tot;j++){if(i*prime[j]>maxn) break;check[i*prime[j]]=true;if(i%prime[j]==0){mu[i*prime[j]]=0;break;}else{mu[i*prime[j]]=-mu[i];}}}
}
int sum[maxn+10];
ll solve(int n,int m){ll ans=0;if(n>m) swap(n,m);for(int i=1,la=0;i<=n;i=la+1){la=min(n/(n/i),m/(m/i));ans+=(ll)(sum[la]-sum[i-1])*(n/i)*(m/i);}return ans;
}
int main()
{Moblus();sum[0]=0;for(int i=1;i<=maxn;i++){sum[i]=sum[i-1]+mu[i];}int a,b,c,d,k;scanf("%d%d%d%d",&a,&b,&c,&d);k=1;ll ans=solve(b/k,d/k)-solve((a-1)/k,d/k)-solve(b/k,(c-1)/k)+solve((a-1)/k,(c-1)/k);printf("%lld\n",ans);return 0;
}

Problem C

题意:

给你nnn个数,让你在其中选取mmm个,要求这mmm个数中不能有相同数字的数。现在问你方案数。

分析:

乍一看好像是一个组合数推公式的问题,但是我们发现,对于每一种数,都会存在取与不取两种状态,因此不好直接用组合数公式递推。

实际上,当我们把题目所给的所有的数都离散化之后,我们发现,这个问题就转化为:给你n′n'n′种数,每种数有numinum_inumi​个,现在要问在这n′n'n′种数中选kkk个数的方案数。

因此我们可以把这个问题转化成010101背包问题。我们设dp[i][j]\text{dp[i][j]}dp[i][j]为前iii种颜色中,有jjj种颜色已经被取了的方案数。而对于当前的状态dp[i][j]\text{dp[i][j]}dp[i][j],显然当前的状态是由前i−1i-1i−1种颜色的取和不取这两种状态转移过来的。因此不难有状态转移方程dp[i][j]=dp[i-1][j-1]*a[i]+dp[i-1][j]\text{dp[i][j]=dp[i-1][j-1]*a[i]+dp[i-1][j]}dp[i][j]=dp[i-1][j-1]*a[i]+dp[i-1][j]

代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+7;
typedef long long ll;
const int mod=998244353;
ll dp[maxn][maxn];
unordered_map<int,int>mp;
int a[maxn];
int main(){// freopen("in.txt","r",stdin);ios::sync_with_stdio(false);cin.tie(0);int n,k,x,cnt=0;cin>>n>>k;for (int i=1;i<=n;i++) {cin>>x;if (!mp.count(x)) mp[x]=++cnt,a[cnt]=1;else a[mp[x]]++;}dp[0][0]=1;for (int i=1;i<=cnt;i++) dp[i][0]=1;for (int i=1;i<=cnt;i++){for (int j=1;j<=k;j++) {dp[i][j]=(dp[i][j]+dp[i-1][j-1]*a[i]%mod)%mod;dp[i][j]=(dp[i][j]+dp[i-1][j])%mod;}}cout<<dp[cnt][k]<<endl;return 0;
}

Problem D

题意:

给你一个数kkk和bbb,问你在0…2b0\dots 2^b0…2b内,被kkk整除的数中内的二进制位的111的个数。

分析:

要统计一段区间内的答案,我们比较常用的做法是通过数位dpdpdp。

但是在这个题中,因为bbb最大为128128128,而鉴于cf\text{cf}cf无int128\text{int128}int128,因此我们无法采用状压的方法进行数位dpdpdp。

因此我们考虑直接对二进制数进行数位dpdpdp。

我们设dp[pos][one][mo]\text{dp[pos][one][mo]}dp[pos][one][mo]代表,当前有pospospos个二进制位,且累计了oneoneone个111,且此时的位数的倍数是momomo。

之后我们只需要枚举0/10/10/1两个数位,并不断累计dfs(pos-1,one+i,(mo*2+i)%k)\text{dfs(pos-1,one+i,(mo*2+i)\%k)}dfs(pos-1,one+i,(mo*2+i)%k)即为答案。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+9;
ll dp[130][130][1007],p[130];
bool a[130];
int b,k;
ll dfs(int pos,int one,int mo){if (pos==-1) {if (mo==0) return one;return 0;}if (dp[pos][one][mo]!=-1) return dp[pos][one][mo];ll res=0;for (int i=0;i<=1;i++){res=(res+dfs(pos-1,one+i,(mo*2+i)%k))%mod;}dp[pos][one][mo]=res;return res;
}
int main()
{//freopen("in.txt","r",stdin);ios::sync_with_stdio(false);cin.tie(0);cin>>k>>b;memset(dp,-1,sizeof dp);for (int i=0;i<b;i++) a[i]=1;cout<<dfs(b-1,0,0)<<endl;return 0;
}

Problem E

题意:

在一个n∗mn*mn∗m的平面图中,一个匪徒位于(xB,yB)(x_B,y_B)(xB​,yB​)处,现在他想要逃出这个图。现在警察想要设置路障阻碍匪徒逃跑。现在平面图中有kkk种地形,在第iii种地形布置路障需要花费valival_ivali​元。现在问你最少花费多少钱才能阻止匪徒逃跑。

分析:

如果直接暴力搜显然太过复杂,因此我们考虑如何进行转化。

我们发现,这个题的的目的是阻止匪徒逃跑,换句话说,就是阻止匪徒走到边界点。即,让倘若我们把匪徒看成源点,边界点看作汇点,则我们现在想要做的即是求出切断源点与汇点的最小花费。而这个即是最小割。

而在这个问题中,因为部分点含有的是点权而不是边权,因此我们考虑进行拆点。我们将能设路障的点拆成两个点,继而使得点权转化为边权,而其他的点我们就分别跟超级源点和超级汇点连一条流量为无穷大的边。之后我们只需要在我们所构建的图上跑最大流即为答案。

#include <bits/stdc++.h>
#define maxn 10005
using namespace std;
struct Node{int to,next,val,w;
}q[maxn];
int head[maxn],cur[maxn],cnt,dep[maxn],vis[maxn],sp,tp;
const int INF=0x3f3f3f3f;
void add_edge(int from,int to,int val){q[cnt].to=to;q[cnt].val=val;q[cnt].next=head[from];head[from]=cnt++;q[cnt].to=from;q[cnt].val=0;q[cnt].next=head[to];head[to]=cnt++;
}
bool bfs(){int vis[maxn];memset(dep,INF,sizeof(dep));memset(vis,0,sizeof(vis));queue<int>que;dep[sp]=0;que.push(sp);while(!que.empty()){int x=que.front();que.pop();vis[x]=0;for(int i=head[x];i!=-1;i=q[i].next){int to=q[i].to;if(dep[to]>dep[x]+1&&q[i].val){dep[to]=dep[x]+1;if(vis[x]==0)que.push(to);vis[to]=1;}}}if(dep[tp]!=INF) return 1;else return 0;
}
int dfs(int u,int flow){int rlow=0;if(u==tp)return flow;for(int i=cur[u];i!=-1;i=q[i].next){int d=q[i].to;cur[u]=1;if(q[i].val&&dep[d]==dep[u]+1){if(rlow=dfs(d,min(flow,q[i].val))){q[i].val-=rlow;q[i^1].val+=rlow;return rlow;}}}return 0;
}
int Dinic(){int total=0,tt;int lowflow=0;while(bfs()){memcpy(cur,head,sizeof(head));while(lowflow=dfs(sp,INF)) total+=lowflow;}return total;
}
int a[maxn];
char str[maxn][maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int main()
{int n,m,k;memset(head,-1,sizeof(head));cnt=0;scanf("%d%d%d",&m,&n,&k);for(int i=0;i<n;i++){scanf("%s",str[i]);}for(int i=0;i<k;i++){scanf("%d",&a[i]);}sp=2*n*m+100,tp=sp+1;for(int i=0;i<n;i++){for(int j=0;j<m;j++){int u=i*m+j;if(str[i][j]=='.'||str[i][j]=='B')add_edge(u,u+n*m,INF);else add_edge(u,u+n*m,a[str[i][j]-'a']);for(int k=0;k<4;k++){int ii=i+dx[k];int jj=j+dy[k];if(ii>=n||ii<0||jj>=m||jj<0)add_edge(u+n*m,tp,INF);else add_edge(u+n*m,(ii*m+jj),INF);}if(str[i][j]=='B')add_edge(sp,u,INF);}}int res=Dinic();if(res>=INF) puts("-1");else cout<<res<<endl;return 0;
}

Problem F

复习了一边扫描线……

在扫描线中(假设我们顺着xxx轴平行的线进行扫描),我们把一个矩形分为上下两条线,其中下线的值为111,上线的值为−1-1−1。在我们扫描每一条线之后,我们会对当前这条扫描线所映射的区间(即区间[x1,x2][x_1,x_2][x1​,x2​])进行区间更新(区间更新1或−11或-11或−1)。而每次扫描后,如果线段树维护的某个的映射区间的标记值大于111,则说明当前当前这个区间能够对答案有贡献,则就将改段区间对应的值累加,并向根部更新。最后树顶所表示的值即为在原图矩形中横坐标能贡献的大小sizesizesize,最后我们将这个大小乘上前后两条扫描线所加的纵坐标的大小即为对于两条扫描线下的答案贡献。

扫描线的难点在于离散化后各个数值之间的关系。

题意:

给你nnn个矩形,让你求这nnn个矩形中的被覆盖的次数为奇数的面积并。

分析:

因为有了,奇数次的限制,因此我们需要考虑如何在原来的扫描线的基础下进行更改。

我们发现,对于扫描线所映射的区间,倘若被更新奇数次,则该段区间所对应的值能对答案有贡献;否则则没有贡献。因此我们发现,在这个问题中,我们只需要对标记维护奇偶,如果当前区间的标记为奇,则当前所映射的答案能够贡献,反之则不能。因此我们只需要在把之前的区间加法更新改成区间异或更新,如果lazy\text{lazy}lazy为111,则统计答案即可。

#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
struct Node{int x1,x2,y,w;Node(){}Node(int _x1,int _x2,int _y,int _w){x1=_x1,x2=_x2,y=_y,w=_w;}bool operator <(const Node &b)const{return y<b.y;}
}q[maxn*2];
struct ST{int sum,lazy;
}tr[maxn<<2];
void push_up(int rt){tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
}
int S[maxn];
void push_down(int l,int r,int rt){if(tr[rt].lazy!=0){int mid=(l+r)>>1;tr[rt<<1].sum=S[mid]-S[l-1]-tr[rt<<1].sum;tr[rt<<1|1].sum=S[r]-S[mid]-tr[rt<<1|1].sum;tr[rt<<1].lazy^=1;tr[rt<<1|1].lazy^=1;tr[rt].lazy=0;}
}
void update(int L,int R,int l,int r,int rt){if(L<=l&&R>=r){tr[rt].sum=S[r]-S[l-1]-tr[rt].sum;tr[rt].lazy^=1;return ;}push_down(l,r,rt);int mid=(l+r)>>1;if(L<=mid) update(L,R,l,mid,rt<<1);if(R>mid) update(L,R,mid+1,r,rt<<1|1);push_up(rt);
}
int main()
{int n;scanf("%d",&n);int tot=0,cnt=0;for(int i=1;i<=n;i++){int x1,y1,x2,y2;if(x1>x2) swap(x1,x2);if(y1>y2) swap(y1,y2);scanf("%d%d%d%d",&x1,&y1,&x2,&y2);q[++cnt]=Node(x1,x2,y1,1);q[++cnt]=Node(x1,x2,y2,-1);S[++tot]=x1;S[++tot]=x2;}sort(q+1,q+1+cnt);sort(S+1,S+1+tot);tot=unique(S+1,S+1+tot)-S-1;long long res=0;for(int i=1;i<=cnt;i++){int l=lower_bound(S+1,S+1+tot,q[i].x1)-S;int r=lower_bound(S+1,S+1+tot,q[i].x2)-S;if(l<=r) update(l+1,r,1,tot,1);if(i!=cnt){res+=1ll*tr[1].sum*(q[i+1].y-q[i].y);}}printf("%lld\n",res);return 0;
}

Problem G

题意:

给你一个矩形以及矩形外的一个点ppp,现在要以ppp为圆心,半径为rrr,现在求这个圆不与矩形相交的最大的半径。

分析:

分为三种情况进行讨论:

  1. 如果点ppp的xxx轴坐标在矩形的与xxx轴平行的边的范围内,则显然答案为点ppp到最近的一条平行于xxx轴的距离。
  2. 如果点ppp的yyy轴坐标在矩形的与yyy轴平行的边的范围内,则显然答案为点ppp到最近的一条平行于yyy轴的距离。
  3. 如果不属于上述两个条件,则答案为点ppp到里它最近的顶点的距离。
代码:
#include <bits/stdc++.h>
using namespace std;
double eps=1e-8;
int sgn(double x){if(fabs(x)<eps) return 0;if(x<0) return -1;else return 1;
}
struct Point{double x,y;Point(){}Point(double _x,double _y){x=_x,y=_y;}double operator ^(const Point &b)const{return x*b.y-y*b.x;}double operator *(const Point &b)const{return x*b.x+y*b.y;}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}double distance(Point p){return hypot(x-p.x,y-p.y);}
};
struct Line{Point s,e;Line(){}Line(Point _s,Point _e){s=_s;e=_e;}double length(){return s.distance(e);}double dispointtoline(Point p){return fabs((p-s)^(e-s))/length();}
};
int main()
{//freopen("in.txt","r",stdin);Point a,b,c;scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y);Line l[4];l[0]=Line(b,Point(b.x,c.y));l[1]=Line(b,Point(c.x,b.y));l[2]=Line(c,Point(b.x,c.y));l[3]=Line(c,Point(c.x,b.y));double res;double x1=min(l[1].s.x,l[1].e.x);double x2=max(l[1].s.x,l[1].e.x);double y1=min(l[0].s.y,l[0].e.y);double y2=max(l[0].s.y,l[0].e.y);if(a.x<=x2&&a.x>=x1){res=1e18;res=min(res,l[1].dispointtoline(a));res=min(res,l[2].dispointtoline(a));}else if(a.y<=y2&&a.y>=y1){res=1e18;res=min(res,l[0].dispointtoline(a));res=min(res,l[3].dispointtoline(a));}else{double tmp=a.distance(b);double tmp1=a.distance(c);double tmp2=a.distance(Point(b.x,c.y));double tmp3=a.distance(Point(c.x,b.y));res=min(tmp,min(tmp1,min(tmp2,tmp3)));}printf("%.3f\n",res);return 0;
}

Problem H

把素数筛出来,模拟一下题目的内容……然后就过了?

#include <bits/stdc++.h>
using namespace std;
const int maxn=1000005;
int prime[maxn+1];
bool p[maxn+1];
void getPrime(){memset(prime,0,sizeof(prime));for(int i=2;i<=maxn;i++){if(!prime[i]) prime[++prime[0]]=i,p[i]=1;for(int j=1;j<=prime[0]&&prime[j]<=maxn/i;j++){prime[prime[j]*i]=1;if(i%prime[j]==0) break;}}
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);getPrime();int n;cin>>n;int ans=0,x=n;while (x>=4){ans++;for (int j=x;j>=2;j--)if (p[j]&&p[x-j]) {x=j-x+j;break;}}cout<<ans<<endl;return 0;
}

Problem I


Problem J

温暖的签到题

代码:
#include <bits/stdc++.h>
using namespace std;int main()
{int n,s;cin>>n>>s;int maxx=0;for(int i=1;i<=n;i++){int num;cin>>num;maxx=max(maxx,num);}maxx*=s;int res=(maxx+999)/1000;cout<<res<<endl;
}

Problem K


Problem L

温暖的签到题+1

#include <bits/stdc++.h>
using namespace std;
const int maxn=1007;
int a[maxn],b[maxn];
int main()
{ios::sync_with_stdio(false);cin.tie(0);int n,ans=-1;cin>>n;for (int i=1;i<=n;i++) cin>>a[i]>>b[i];for (int i=0;i<=n;i++){int sum=0;for (int j=1;j<=n;j++)if (a[j]<=i&i<=b[j]) sum++;if (i==sum) ans=max(ans,i);}cout<<ans<<endl;return 0;
}

Problem M

转载于:https://www.cnblogs.com/Chen-Jr/p/11007147.html

Gym 101982 (2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) )相关推荐

  1. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    gdcpc前一天上午搞了场训练,水题挺多,还算增强信心.(这么简单的题目居然还是div1,这赛区-- 最终9题,平均每人3题,我写ACF.被hry压了一道E (难受啊. 下午去中大试机,win7系统就 ...

  2. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 【部分题解】

    A:因为删除是不计入操作次数的,所以转化一下就是求最长上升子序列,简单dp. 设dp[i]表示前i个字符能凑成上升子序列的最大长度,dp[i] = max(dp[j]+1, dp[i]) [j < ...

  3. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) - D Count The Bits

    题目链接 Given an integer k and a number of bits b (1 ≤ b ≤ 128), calculate the total number of 1 bits i ...

  4. 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)DCount The Bits(dp/数位dp)

    D Count The Bits 题意: 输入k,b(1≤k≤1000,1≤b≤128);k,b(1\leq k\leq 1000,1\leq b\leq128);k,b(1≤k≤1000,1≤b≤1 ...

  5. 2016 ACM / ICPC Asia dalian Regional Contest 题解(11 / 11)【每日亿题2021 / 2 / 17】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A .(2017 ACM ICPC dalian H)To begin or not to be ...

  6. 2017 ACM ICPC Asia Shenyang Regional Contest 题解(10 / 13)【每日亿题2 / 16】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A.(2017 ICPC shenyang I)Little Boxes B.(2017 ICP ...

  7. Gym 101845(2018 ACM-ICPC, Universidad Nacional de Colombia Programming Contest)

    Problem A Problem B 分析: 暴力查找,由操作111,我们可以知道原串的第一位可以匹配结果串的每一位,所以O(n)\mathcal{O}(n)O(n)枚举对齐判断就好:由操作222, ...

  8. 2013-2014 ACM-ICPC Pacific Northwest Regional Contest题解

    ProblemSet A by ? B by ? 先Floyd求出两两之间最短路. 二分答案,新建一个图,<=x点对连距离为1的边 再施展Floyd,判断,最远两点距离<=k C by ? ...

  9. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

最新文章

  1. 微信小程序实践_4显示新闻(2)
  2. 一起谈.NET技术,Silverlight 游戏开发小技巧:动感小菜单
  3. 理解extract_patches_2d
  4. 新手入门 | 上链第一步,如何完成XuperChain环境、服务部署
  5. 方法的重载与重写_深入解析JAVA重载与重写的区别
  6. php base64尺寸,PHP base64编码的图像显示不正确
  7. 04-numpy-笔记-transpose
  8. Hue添加RDBMS(关系型数据库)
  9. VBA打开TXT类文件读写相关操作代码
  10. 22.Silverlight使用WebService调用C++,Delphi编写的DLL文件
  11. 我晕,原来是这个问题!
  12. Atitti html5 h5 新特性attilax总结
  13. 国际项目投标那些事(四)怎么读海外项目招标文件
  14. 为什么建议向你的同事屏蔽朋友圈?
  15. 深入探索 Android 网络优化(二、网络优化基础篇)上
  16. Nio实现高性能聊天系统
  17. Base—3.0 SPI
  18. 上海海洋大学计算机专业是几本,上海海洋大学是几本 录取分数线一般在多少...
  19. Android基础:Android概念
  20. 创业者觉得苦逼得真正原因

热门文章

  1. printf and echo
  2. Linux 创建进程与关闭进程详解
  3. 胶囊路由_评论:胶囊之间的动态路由
  4. Linux dbm轻量级数据库介绍与使用
  5. 京东连续亏损十几年,为什么却发展越来越大?
  6. 想创业没有资金,如何获得启动资金?
  7. 有无关通配符的相等操作符
  8. 驱动程序和应用程序之间的体系结构不匹配_修复Win10上的黑屏问题全攻略,并不高深,一看就会...
  9. linux 命令 记忆方法,linux 记忆命令心得
  10. java复制的函数会报错,2 面试题之面向对象