NCPC 2016:简单题解
A .Artwork
pro:给定N*M的白色格子,然后Q次黑棒,输出每次加黑棒后白色连通块的数量。(N,M<1e3, Q<1e4)
sol:倒着离线做,并查集即可。
(在线做法:https://www.cnblogs.com/asdfsag/p/10485607.html
#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 = 1e6 + ;
int a[][], fa[maxn], ID[][];
struct node
{
int x1, y1, x2, y2;
node(){}
node(int x1, int y1, int x2, int y2):x1(x1), y1(y1), x2(x2), y2(y2){}
}c[maxn];
int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
int dir[][] = {,,,,-,,,-};
stack<int>s;
int main()
{
int n, m, q, tot = , x1, y1, x2, y2;
scanf("%d%d%d", &n, &m, &q);
for(int i = ; i <= n; i++)for(int j = ; j <= m; j++){ID[i][j] = ++tot; fa[tot] = tot;}
for(int i = ; i <= q; i++)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
c[i] = node(x1, y1, x2, y2);
for(int x = x1; x <= x2; x++)for(int y = y1; y <= y2; y++)a[x][y]++;
}
int white = , cnt = ;
for(int i = ; i <= n; i++)for(int j = ; j <= m; j++)if(!a[i][j])
{
white++;
for(int k = ; k < ; k++)
{
int x = i + dir[k][], y = j + dir[k][];
if(x >= && x <= n && y >= && y <= m && !a[x][y])
{
int u = ID[i][j], v = ID[x][y];
u = Find(u);v = Find(v);
if(u != v)fa[u] = v, cnt++;
}
}
}
s.push(white - cnt);
for(int i = q; i >= ; i--)
{
for(int x = c[i].x1; x <= c[i].x2; x++)
for(int y = c[i].y1; y <= c[i].y2; y++)
{
a[x][y]--;
if(!a[x][y])
{
white++;
for(int k = ; k < ; k++)
{
int xx = x + dir[k][], yy = y + dir[k][];
if(xx >= && xx <= n && yy >= && yy <= m && !a[xx][yy])
{
int u = ID[x][y], v = ID[xx][yy];
u = Find(u);v = Find(v);
if(u != v)fa[u] = v, cnt++;
}
}
}
}
s.push(white - cnt);
}
while(!s.empty()){cout<<s.top()<<endl;s.pop();}
return ;
}
C .Card Hand Sorting
pro:给定N张扑克牌,保证来自一副牌,有四种花色。现在让你重排,同种花色放一起,内部递增或者递减。 重排的方式是抽出一张牌,插入到某位置。
sol:四种花色,枚举花色的排列,再枚举每种花色内是递增还是递减。 对于每种方案,ans=N-LIS。
(写个结构体还是蛮方便的。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
map<char, int>level_num, level_color;
struct node
{
char num, color;
node(){}
node(char num, char color):num(num), color(color){}
bool operator <(const node& now)const
{
if(level_color[color] == level_color[now.color])//花色相同
{
//奇数递增,偶数递减
if(level_color[color] & )return level_num[num] < level_num[now.num];
else return level_num[num] > level_num[now.num];
}
return level_color[color] < level_color[now.color];
}
bool operator == (const node& now)const{return num == now.num && color == now.color;}
}a[], b[];
int dp[][], n;
int solve()
{
memset(dp, , sizeof(dp));
for(int i = ; i <= n; i++)
{
for(int j = ; j <= n; j++)
{
dp[i][j] = max(dp[i - ][j], dp[i][j - ]);
if(a[i] == b[j])dp[i][j] = max(dp[i][j], dp[i - ][j - ] + );
}
}
return n - dp[n][n];
}
char s[] = "shdc";
int c[];
int main()
{
int tot = ;
for(char i = ''; i <= ''; i++)level_num[i] = ++tot;
level_num['T'] = ++tot;level_num['J'] = ++tot;level_num['Q'] = ++tot;
level_num['K'] = ++tot;level_num['A'] = ++tot;
cin >> n;
for(int i = ; i <= n; i++){cin >> a[i].num >> a[i].color;b[i] = a[i];}
for(int i = ; i <= ; i++)c[i] = i;
int ans = n;
do
{
for(int i = ; i <= ; i++)level_color[s[i - ]] = c[i];
for(int i = ; i < ( << ); i++)
{
for(int j = ; j < ; j++)
{
level_color[s[j]] *= ;
if(i & ( << j))level_color[s[j]]++;
}
sort(b + , b + + n);
ans = min(ans, solve());
}
}while(next_permutation(c + , c + ));
cout<<ans<<endl;
return ;
}
D .Daydreaming Stockbroker
pro:开始你有100元,给出N天的股价单价,你每天可以选择用当时的价格交易。限制持有股份不超过100000, 问最后有多少钱。N<365;
sol:枚举之前哪天买即可。
#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 a[maxn],dp[maxn],ans=;
int main()
{
int N;
scanf("%d",&N);
rep(i,,N) scanf("%lld",&a[i]);
dp[]=dp[]=;
rep(i,,N){
rep(j,,i-){
ll t=min(dp[j]/a[j],100000LL);
dp[i]=max(t*a[i]+dp[j]-t*a[j],dp[i]);
}
ans=max(ans,dp[i]);
dp[i+]=max(dp[i+],dp[i]);
}
printf("%lld\n",ans);
return ;
}
E .Exponial
pro:给定N,M。求。N^((N-1)^(N-2)...)%M;(N,M<1e9)
sol:显然欧拉降幂。 注意幂>mod时才能降幂,4以内的小于1e9,所以特判。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,m;
int phi(int x){
int ans=x;
for(int i=;i*i<=x;i++)
if(x%i==){
ans/=i;ans*=i-;
while(x%i==) x/=i;
}
//cout<<x<<" "<<ans<<" "<<endl;;
if(x>) ans/=x,ans*=x-;
return ans;
}
int ksm(int x,int y,int p){
int ans=;
for(;y;y>>=){
if(y&)ans=(ll)ans*x%p;
x=(ll)x*x%p;
}
return ans;
}
int dfs(int x,int y){
if(y==) return ;
if(x==) return ;
if(x==) return ksm(x,,y);
if(x==) return ksm(x,,y);
if(x==) return ksm(x,,y);
if(x==) return x%y; int ph=phi(y);
return ksm(x,dfs(x-,ph)+ph,y);
}
int main(){
scanf("%d%d",&n,&m);
printf("%d",dfs(n,m));
return ;
}
G .Game Rank
排位模拟题。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,lev=,st,wins;
char s[];
int main(){
scanf("%s",s+);
n=strlen(s+);
for(int i=;i<=n;i++){
if(s[i]=='W'){
if(lev>=&&wins>=)st+=,wins++;
else st++,wins++;
while(lev>&&st>)lev--,st-=;
while(lev>&&st>)lev--,st-=;
while(lev>&&st>)lev--,st-=;
while(st>)lev--,st-=;
}
else{
wins=;
if(lev<=)st--;
if(st<){
lev++;
if(lev>)lev=,st=;
else if(lev>)st=;
else if(lev>)st=;
else st=;
}
}
if(lev<=)return *puts("Legend");
}
printf("%d",lev);
return ;
}
H .Highest Tower
pro:BZOJ4886
sol:定向问题。 不难证明最后是一棵或者多棵树或者环套树。 证明https://blog.csdn.net/V5ZSQ/article/details/79337446?utm_source=blogxgwz8
#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=;
map<int,int>mp;
int ind[maxn],tot,mx[maxn],fa[maxn],tag[maxn],val[maxn]; ll ans;
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
int u[maxn],v[maxn];
int main()
{
int N,x,y;
scanf("%d",&N);
rep(i,,N){
scanf("%d%d",&u[i],&v[i]);
x=u[i]; y=v[i];
if(!mp[x]) mp[x]=++tot,val[tot]=mx[tot]=x;
if(!mp[y]) mp[y]=++tot,val[tot]=mx[tot]=y;
x=u[i]=mp[x]; y=v[i]=mp[y];
ind[x]++; ind[y]++;
}
rep(i,,tot) fa[i]=i;
rep(i,,tot){
x=find(u[i]); y=find(v[i]);
if(tag[x]&&tag[y]) continue;
if(x==y) tag[y]=;
else fa[x]=y,tag[y]|=tag[x],mx[y]=max(mx[x],mx[y]);
}
rep(i,,tot){
ans+=1LL*(ind[i]-)*val[i];
if(find(i)==i&&!tag[i]) ans+=mx[i];
}
printf("%lld\n",ans);
return ;
}
J .Jumbled Compass
模拟。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=;i++){
if((n+i)%==m)return *printf("%d",i);
if((n-i+)%==m)return *printf("%d",-i);
}
}
K .Keeping the Dogs Apart
题意: 给定两支猫的行走路线, 都是直线行走, 求他们都在走的最近距离.
思路: 模拟即可. 每次得到min{到转折点的时间}, 然后得到结束位置, 至于这个过程的最近距离,我们可以假设一个不动,那么就是点到线段的距离. 继续模拟.
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
double x[maxn][],y[maxn][],ans;
const double inf=1e200;
const double pi=*atan(1.0);
struct point{
double x,y;
point(double a=,double b=):x(a),y(b){}
};
int dcmp(double x){ return fabs(x)<0.0000000000001?:(x<?-:);}
point operator +(point A,point B) { return point(A.x+B.x,A.y+B.y);}
point operator -(point A,point B) { return point(A.x-B.x,A.y-B.y);}
point operator *(point A,double p){ return point(A.x*p,A.y*p);}
point operator /(point A,double p){ return point(A.x/p,A.y/p);}
point rotate(point A,double rad){
return point(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
}
bool operator ==(const point& a,const point& b) {
return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
}
double dot(point A,point B){ return A.x*B.x+A.y*B.y;}
double det(point A,point B){ return A.x*B.y-A.y*B.x;}
double dot(point O,point A,point B){ return dot(A-O,B-O);}
double det(point O,point A,point B){ return det(A-O,B-O);}
double length(point A){ return sqrt(dot(A,A));}
double angle(point A,point B){ return acos(dot(A,B)/length(A)/length(B));}
bool isPointOnSegment(point p,point a1,point a2)
{
//点是否在线段上
return dcmp(det(a1-p,a2-p)==&&dcmp(dot(a1-p,a2-p))<=);
}
double distoseg(point P,point A,point B)
{
if(isPointOnSegment(P,A,B)) return 0.0;
//点到线段距离
if(A==B) return length(P-A);
point v1=B-A,v2=P-A,v3=P-B;
if(dcmp(dot(v1,v2))<) return length(v2);
else if(dcmp(dot(v1,v3))>) return length(v3);
return fabs(det(v1,v2)/length(v1));
}
double dist(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void solve(int A,int B,double t)
{
double dx[],dy[];
double d1=dist(x[A][],y[A][],x[A+][],y[A+][]);
double d2=dist(x[B][],y[B][],x[B+][],y[B+][]);
dx[]=(x[A+][]-x[A][])/d1; dy[]=(y[A+][]-y[A][])/d1;
dx[]=(x[B+][]-x[B][])/d2; dy[]=(y[B+][]-y[B][])/d2;
double sx=x[A][],sy=y[A][],tx=x[A][]+(dx[]-dx[])*t,ty=y[A][]+(dy[]-dy[])*t;
double res=distoseg(point(x[B][],y[B][]),point(sx,sy),point(tx,ty));
ans=min(ans,res);
x[A][]+=dx[]*t; y[A][]+=dy[]*t;
x[B][]+=dx[]*t; y[B][]+=dy[]*t;
}
int main()
{
int N,M;
scanf("%d",&N);
rep(i,,N) scanf("%lf%lf",&x[i][],&y[i][]);
scanf("%d",&M);
rep(i,,M) scanf("%lf%lf",&x[i][],&y[i][]);
ans=;
int A=,B=;
while(A<N&&B<M){
double da=dist(x[A][],y[A][],x[A+][],y[A+][]);
double db=dist(x[B][],y[B][],x[B+][],y[B+][]);
if(da<db){
solve(A,B,da);
A++;
}
else if(da==db){
solve(A,B,da);
A++; B++;
}
else {
solve(A,B,db);
B++;
}
}
printf("%.8lf\n",ans);
return ;
}
NCPC 2016:简单题解的更多相关文章
- [补档][HZOI 2016]简单的Treap
[HZOI 2016]简单的Treap 题目 Treap是一种平衡二叉搜索树,除二叉搜索树的基本性质外,Treap还满足一个性质: 每个节点都有一个确定的优先级,且每个节点的优先级都比它的两个儿子小( ...
- cogs——2478. [HZOI 2016]简单的最近公共祖先
2478. [HZOI 2016]简单的最近公共祖先 ★☆ 输入文件:easy_LCA.in 输出文件:easy_LCA.out 简单对比时间限制:2 s 内存限制:128 MB [题 ...
- cogs 2478. [HZOI 2016]简单的最近公共祖先
2478. [HZOI 2016]简单的最近公共祖先 ★☆ 输入文件:easy_LCA.in 输出文件:easy_LCA.out 简单对比时间限制:2 s 内存限制:128 MB [题 ...
- COGS 2421.[HZOI 2016]简单的Treap 题解
题目大意: 给定n个数及其优先级,求对应的符合最小堆性质的Treap的先序遍历. n<=500000. 解法: 目前为止我只想到了三种解法,其中第三种是正解. 1.暴力1 以优先级为关键字排序, ...
- COGS——T 2478. [HZOI 2016]简单的最近公共祖先
http://www.cogs.pro/cogs/problem/problem.php?pid=2478 ★☆ 输入文件:easy_LCA.in 输出文件:easy_LCA.out 简单 ...
- CF449 (Div. 1简单题解)
A .Jzzhu and Chocolate pro:现在给定一个大小为N*M的巧克力,让你横着或者竖着切K刀,都是切的整数大小,而且不能切在相同的地方,求最大化其中最小的块. (N,M,K<1 ...
- CF446 (Div. 1)简单题解
A .DZY Loves Sequences pro:给定长度为N的序列,你最多可以改变一个数的值,问最长严格上升子序列长度. N<1e5. sol:分几种情况,一种的不改变: 一种是改变,然后 ...
- Game Rank(NCPC 2016 大模拟)
题目: The gaming company Sandstorm is developing an online two player game. You have been asked to imp ...
- Noip 2016 愤怒的小鸟 题解
[NOIP2016]愤怒的小鸟 时间限制:1 s 内存限制:256 MB [题目描述] Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0, ...
随机推荐
- js正则表达式 replace替换url的参数
/* 定义替换对象键值 */var setReferArgs = function(){ var referArgs = new Object(); referArgs['#userID\ ...
- CentOS中/英文环境切换教程(CentOS6.8)
一.前言 对于不习惯英文的人可能想将系统由英文转成中文:而对于考虑客户端如果没正确配置,中文目录可能显示为乱码的人则可能宁愿将系统由中文转成英文. 中文切换为英文,实际就是将LANG的值由zh_CN- ...
- e2e 测试(1)
距离上一随笔,已经有一个月没有没写.到今天,刚刚好好,是学习e2e测试的一个月.今天有点时间可以总结一下这个月来的收获. 1.搭建e2e的测试环境 我是使用 Vue 构建项目,所以我也是通过Vue-c ...
- 关于JAVA的一些知识点
1.java.lang.Runtime.getRuntime().availableProcessors() Returns the number of processors available to ...
- 锚点 , angular 锚点 vue锚点
因为最近在开发angular,自己有路由 用window.location跳到默认路由,查了半天用angular方式不好解决 ,so 原生走起 START scrollIntoView是一个与页面(容 ...
- python xlrd使用
python xlrd使用 1● xlrd安装 管理员模式 success 2● 引用 import xlrd
- pickle file in matlab
Load pickle files in Matlab Posted on June 12, 2013 by xcorr http://xcorr.net/2013/06/12/load-pick ...
- NSIS笔记
1.IfFileExists IfFileExists D:\SA\test\testdirectory\*.* 0 +1 判断testdirectory是否是一个目录,若是,则执行接下来的第一行代码 ...
- react router @4 和 vue路由 详解(全)
react router @4 和 vue路由 本文大纲: 1.vue路由基础和使用 2.react-router @4用法 3.什么是包容性路由?什么是排他性路由? 4.react路由有两个重要的属 ...
- python 调用zabbix api实现查询主机信息,输出所有主机ip
之前发现搜索出来的主机调用zabbix api信息都不是那么明确,后来通过zabbix官方文档,查到想要的api信息,随后写一篇自己这次项目中用到的api. #!/usr/bin/env python ...