本套题没有什么数据结构题,图论题,唯一有价值的就是Q题博弈,在最后面,读者可以直接拉到最下面。

(还剩下两个,估计每什么价值的题,懒得补了

M .Polyhedra

pro:欧拉公式,V-E+F=2;给定V,E,求F

sol:F=E-V+2;

#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 T;
scanf("%d", &T);
while(T--)
{
int a, b;
scanf("%d%d", &a, &b);
printf("%d\n", b - a + );
}
return ;
}

N .Majority

pro:  给定一些一些1到1000的数字,问最小的出现次数最多的数字。

sol:  模拟。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int num[maxn];
int main()
{
int T,N,x;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
rep(i,,) num[i]=;
rep(i,,N){
scanf("%d",&x);
num[x]++;
}
int ans=,x=-;
rep(i,,) {
if(num[i]>x) ans=i,x=num[i];
}
printf("%d\n",ans);
}
return ;
}

O .Diamonds

pro:给定一些二元组,求最长的序列,满足a递增,b递减。

sol:N^2暴力即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
struct in{
double x,y;
}s[maxn];
int dp[];
int main()
{
int T,N,ans;
scanf("%d",&T);
while(T--){
scanf("%d",&N); ans=;
rep(i,,N) scanf("%lf%lf",&s[i].x,&s[i].y);
rep(i,,N){
dp[i]=;
rep(j,,i-){
if(s[j].x<s[i].x&&s[j].y>s[i].y) dp[i]=max(dp[i],dp[j]+);
}
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
return ;
}

R .Ramp Number

pro:一个数字X是合法的,当且仅当各位数字从左到右不降。 如果一个数字的合法,求多少个小于他的数是合法的。

sol:基本数位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[maxn][]; char c[maxn]; int a[maxn],len;
ll dfs(int pos,int lim,int now)
{
if(pos==len) return ;
if(!lim&&dp[pos][now]) return dp[pos][now];
ll res=; int up=; if(lim) up=a[pos+];
rep(j,now,up) res+=dfs(pos+,lim&&j==a[pos+],j);
return dp[pos][now]=res;
}
void solve()
{
ll res=;
rep(i,,len){
memset(dp,,sizeof(dp));
int up=; if(i==) up=a[];
rep(j,,up) res+=dfs(i,i==&&j==up,j);
}
printf("%lld\n",res);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%s",c+);
len=strlen(c+);
rep(i,,len) a[i]=c[i]-'';
bool F=true;
rep(i,,len) if(a[i]<a[i-]) F=false;
if(!F){ puts("-1"); continue;}
solve();
}
return ;
}

X .Wrench

pro:把一个带小数的数字表示为整数 加一个 分数形式,满足分母是2的幂次,而且要越小的满足的,允许有最后一位的误差。

sol:模拟,细节需要注意。

#include<bits/stdc++.h>
using namespace std;
int t,n;
char s[],s1[];
int main(){
for(scanf("%d",&t);t--;){
scanf("%s",s);n=strlen(s);
int p=;bool flag=,flag1=;
while(s[p]==''&&p<n)p++;
while(s[p]!='.'&&p<n)putchar(s[p++]),flag1=;
for(int i=p+;i<n;i++)
if(s[i]!=''){flag=;break;}
if(flag){if(flag1)putchar(' ');}
else{puts("\"");continue;}
flag=;
for(int i=;i<=;i<<=){
for(int j=;j<i;j++){
double x=1.0*j/i;
for(int v=;v<;v++)x*=,s1[v]=(int)x%+'';
bool f=;
for(int k=;p+k<n;k++)
if(s1[k-]!=s[p+k]&&(p+k<n-||s1[k-]+!=s[p+k])){f=;break;}
if(f){printf("%d/%d\"\n",j,i);flag=;break;}
}
if(flag)break;
}
}
return ;
}

U .Top 25

题意:给定A和B,分别是不同的1到N的排列,找到连续的段(越短越好),代表的集合相同。

思路:每次找到对应的位置,如果最远的对应位置和当前相同,说明这段集合相同。

Map+clear: 3525ms

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
map<string, int>Map;
int f[maxn];
vector<int>ans;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int N,x,y;
Map.clear();
string s;
scanf("%d",&N);
rep(i,,N){
cin>>s;
Map[s]=i;
}
rep(i,,N){
cin >> s;
f[Map[s]] = i;
}
rep(i,,N){
if(i==f[i]) printf("1 ");
else{
int maxx = f[i];
for(int j = i + ; j <= maxx; j++){
if(f[j] > maxx)maxx = f[j];
}
printf("%d ",maxx-i+);
i = maxx;
}
}
puts("");
}
return ;
}

Map: 4227ms

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
map<string, int>Map;
int f[maxn];
vector<int>ans;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int N,x,y;
string s;
scanf("%d",&N);
rep(i,,N){
cin>>s;
Map[s]=i;
}
rep(i,,N){
cin >> s;
f[Map[s]] = i;
}
rep(i,,N){
if(i==f[i]) printf("1 ");
else{
int maxx = f[i];
for(int j = i + ; j <= maxx; j++){
if(f[j] > maxx)maxx = f[j];
}
printf("%d ",maxx-i+);
i = maxx;
}
}
puts("");
}
return ;
}

unordered_map:2479ms

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
unordered_map<string, int>Map;
int f[maxn];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
Map.clear();
int N,x,y;
string s;
scanf("%d",&N);
rep(i,,N){
cin>>s;
Map[s]=i;
}
rep(i,,N){
cin >> s;
f[Map[s]] = i;
}
rep(i,,N){
if(i==f[i]) printf("1 ");
else{
int maxx = f[i];
for(int j = i + ; j <= maxx; j++){
if(f[j] > maxx)maxx = f[j];
}
printf("%d ",maxx-i+);
i = maxx;
}
}
puts("");
}
return ;
}

这告诉我们map的效率和map的大小有关,所以要及时的clear。 而我如果用set,一位set一直在erase,元素会慢慢表少,所以二分的速度会更快。

set: 3010ms

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
set<string>s;
string a[maxn],b[maxn];
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int N,x,y,tot=;
scanf("%d",&N);
rep(i,,N) cin>>a[i];
rep(i,,N) cin>>b[i];
rep(i,,N) {
tot++;
if(s.find(a[i])!=s.end()) s.erase(a[i]);
else s.insert(a[i]);
if(s.find(b[i])!=s.end()) s.erase(b[i]);
else s.insert(b[i]);
if(s.empty()) {
printf("%d ",tot);
tot=;
}
}
puts("");
}
return ;
}

(但是主要的时间还是在输入输出那里。

W .Wormhole

pro:给定三维的N个点,有一些点对可以互通,其他的点对距离是欧几里得距离。Q次询问点对最近距离。

sol:folyd。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
typedef long long ll;
struct node
{
double x, y, z;
double operator - (const node& a)const
{
return (sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y) + (z - a.z) * (z - a.z)));
}
}a[maxn];
map<string, int>Map;
double dis[][];
int main()
{
int T, cases = ;
scanf("%d", &T);
while(T--)
{
memset(dis, , sizeof(dis));
Map.clear();
int n, m;
scanf("%d", &n);
string s, s1;
for(int i = ; i <= n; i++)
{
cin >> s >> a[i].x >> a[i].y >> a[i].z;
Map[s] = i;
}
for(int i = ; i <= n; i++)
{
for(int j = i + ; j <= n; j++)
{
dis[i][j] = dis[j][i] = a[i] - a[j];
//cout<<dis[i][j]<<endl;
}
}
cin >> m;
while(m--)
{
cin >> s >> s1;
dis[Map[s]][Map[s1]] = ;
}
for(int k = ; k <= n; k++)
for(int i = ; i <= n; i++)
for(int j = ; j <= n; j++)
dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
cin >> m;
cout<<"Case "<<++cases<<":\n";
while(m--)
{
cin >> s >> s1;
cout<<"The distance from "<<s<<" to "<<s1<<" is "<<(ll)(dis[Map[s]][Map[s1]]+0.5)<<" parsecs.\n";
}
}
return ;
}

V .Towers

pro:给定N,让填数独,然后给出(N+2)*(N+2)的矩阵,里面N*N的数字或者未知,周围4行表示从那个方向看过去的LIS。N<=5

sol:搜索,需要及时减枝。 check函数就是给个方向的判定。 只跑了30ms,估计包本来就可以暴力一点,即到了边界再减枝?

减枝1:对于每填一个数,就看和上面的数字是否有重复。

减枝2:对于每个数,看左边和上边看过去的LIS已经超过题目描述,退出。

判定3:对于右边界和下边界,检查从右和下看过去的LIS。

#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=;
char c[][],ans[][];
int vis[][],N;
int get(int x,int y,int tx,int ty,int X,int Y)
{
int res=,now=;
while(){
x+=tx; y+=ty;
if(ans[x][y]>now) now=ans[x][y],res++;
if(x==X&&y==Y) return res;
}
return res;
}
bool check(int u,int v)
{
rep(i,,u-) if(ans[u][v]==ans[i][v]) return false;
if(c[u][]!='-'){
int t=get(u,,,,u,v);
if(t>c[u][]-'') return false;
if(v==N&&t!=c[u][]-'') return false;
}
if(c[][v]!='-'){
int t=get(,v,,,u,v);
if(t>c[][v]-'') return false;
if(u==N&&t!=c[][v]-'') return false;
}
if(v==N&&c[u][N+]!='-'){
if(get(u,N+,,-,u,)!=c[u][N+]-'') return false;
}
if(u==N&&c[N+][v]!='-'){
if(get(N+,v,-,,,v)!=c[N+][v]-'') return false;
}
return true;
}
bool dfs(int u,int v)
{
if(u==N+&&v==) {
return true;
}
int L=,R=N;
if(c[u][v]!='-') L=R=c[u][v]-'';
rep(i,L,R){
if(!vis[u][i]){
vis[u][i]=; ans[u][v]=i;
if(v<N){
if(check(u,v)){
if(dfs(u,v+)) return true;
}
}
else{
if(check(u,v))
{
if(dfs(u+,)) return true;
}
}
vis[u][i]=;
}
}
return false;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
memset(vis,,sizeof(vis));
rep(i,,N+) scanf("%s",c[i]);
if(!dfs(,)) puts("no\n");
else {
rep(i,,N) {
rep(j,,N) putchar(ans[i][j]+'');
puts("");
}
puts("");
}
}
return ;
}

T .Runes

pro:给定等式,其中有不超过6个问号,让你填一个相同的未出现过的数字,使等式满足。

sol:枚举。注意负号,0等情况。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
typedef long long ll;
bool judge(char s[], int x, ll& y)
{
int n = strlen(s);
char s1[];
memcpy(s1, s, sizeof(s1));
for(int i = ; i < n; i++)
{
if(s1[i] == '?')s1[i] = '' + x;
}
if(s1[] == '-' && s1[] == '')return false;
if(s1[] == '' && n != )return false;
bool flag;
if(s1[] == '-')flag = ;
else flag = ;
y = ;
for(int i = flag; i < n; i++)y = y * + s1[i] - '';
if(flag)y = -y;
}
char s[], s1[], s2[], s3[];
int vis[];
int main()
{
int T, cases = ;
scanf("%d", &T);
while(T--)
{
memset(s1, , sizeof(s1));
memset(s2, , sizeof(s2));
memset(s3, , sizeof(s3));
memset(vis, , sizeof(vis));
scanf("%s", s);
int n = strlen(s), tmp, tmp1;
for(int i = ; i < n; i++)
{
if((isdigit(s[i]) || s[i] == '?') && (s[i + ] == '+' || s[i + ] == '-' || s[i + ] == '*'))
{
tmp = i + ;
break;
}
}
for(int i = ; i < n; i++)if(s[i] == '='){tmp1 = i;break;}
for(int i = ; i < n; i++)if(isdigit(s[i]))vis[s[i] - ''] = ;
for(int i = ; i < tmp; i++)s1[i] = s[i];
for(int i = tmp + , j = ; i < tmp1; i++, j++)s2[j] = s[i];
for(int i = tmp1 + , j = ; i < n; i++, j++)s3[j] = s[i];
bool ok = ;
for(int i = ; i <= ; i++)
{
if(vis[i])continue;
ll a, b, c;
bool flag = ;
if(judge(s1, i, a) && judge(s2, i, b) && judge(s3, i, c))
{
if(s[tmp] == '-' && a - b == c)flag = ;
if(s[tmp] == '+' && a + b == c)flag = ;
if(s[tmp] == '*' && a * b == c)flag = ;
}
if(flag)
{
ok = ;
printf("%d\n", i);
break;
}
}
if(!ok)printf("-1\n");
}
return ;
}

Q .Number Game

pro:双人博弈,给定一个N的排列,Alice先手,Bob后手,他们轮流取,取到数字1的胜,能取走一个数字的条件是两旁没有比它大的数字。

sol:我们发现,只有和1相邻的连续区间是要考虑的; 之外的区间因为一定可以按一定顺序取完,所以只考虑奇偶性。

即用dp[L][R][k]保存先手的情况:[L,R]是当前包含数字1的区间,k是此区间外的未取的个数奇偶性。然后就可以记忆化搜索了。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int dp[maxn][maxn][],a[maxn],pos;
int dfs(int L,int R,int k)
{
if(L==R) return ;
if(dp[L][R][k]!=-)
return dp[L][R][k];
if(k==&&!dfs(L,R,)) dp[L][R][k]=;
rep(i,L,R){
bool F=true;
if(i->=L&&a[i-]>a[i]) F=false;
if(i+<=R&&a[i+]>a[i]) F=false;
if(!F) continue;
if(i==pos) dp[L][R][k]=;
else {
if(i<pos){
if(!dfs(i+,R,(k+i-L)&)) dp[L][R][k]=;
}
else {
if(!dfs(L,i-,(k+R-i)&)) dp[L][R][k]=;
}
}
}
if(dp[L][R][k]==-) dp[L][R][k]=;
return dp[L][R][k];
}
int main()
{
int N,T;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
rep(i,,N){
scanf("%d",&a[i]);
if(a[i]==) pos=i;
}
memset(dp,-,sizeof(dp));
dfs(,N,);
if(dp[][N][]) puts("Alice");
else puts("Bob");
}
return ;
}

Gym-101653:acific Northwest Regional Contest (2019训练第一场)的更多相关文章

  1. 2020.5.4-ICPC Pacific Northwest Regional Contest 2019

    A. Radio Prize All boring tree-shaped lands are alike, while all exciting tree-shaped lands are exci ...

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

    2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) 思路: A Exam 思路:水题 代码: #include<bits ...

  3. 2018 ICPC Pacific Northwest Regional Contest I-Inversions 题解

    题目链接: 2018 ICPC Pacific Northwest Regional Contest - I-Inversions 题意 给出一个长度为\(n\)的序列,其中的数字介于0-k之间,为0 ...

  4. Gym 101655:2013Pacific Northwest Regional Contest(寒假自训第13场)

    A .Assignments 题意:给定距离D,以及N个飞机的速度Vi,单位时间耗油量Fi,总油量Ci.问有多少飞机可以到达目的地. 思路:即问多少飞机满足(Ci/Fi)*Vi>=D  ---- ...

  5. Gym - 101615J Grid Coloring DP 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    题目传送门 题目大意: 给出n*m的网格,有红蓝两种颜色,每个格子都必须被染色,当一个格子被染成蓝色后,这个格子左上方的一块都必须被染成蓝色,问最后的方案数量. 思路: 按照题目条件,如果有一个格子被 ...

  6. Gym - 101982A 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) A. Exam

    题面 题意:你和朋友一起做了n道判断题,现在你知道你们两的答案,也知道你朋友对了k个,问你至少对了几个 题解:假设你和朋友n个答案都一样,那你是不是也对了k个,假设你和朋友有1个答案不一样,是不是,你 ...

  7. Gym - 101982B 2018-2019 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) B. Coprime Integers Mobius+容斥 ab间gcd(x,y)=1的对数

    题面 题意:给你 abcd(1e7),求a<=x<=b,c<=y<=d的,gcd(x,y)=1的数量 题解:经典题目,求从1的到n中选x,从1到m中选y的,gcd(x,y)=k ...

  8. 2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) S Surf

    SurfNow that you've come to Florida and taken up surng, you love it! Of course, you've realized that ...

  9. Contest Setting 2018 ICPC Pacific Northwest Regional Contest dp

    题目:https://vj.69fa.cn/12703be72f729288b4cced17e2501850?v=1552995458 dp这个题目网上说是dp+离散化这个题目要对这些数字先处理然后进 ...

随机推荐

  1. 漫谈moosefs中cgi各项的意义

    原创:http://www.cnblogs.com/bugutian/p/6869278.html 转载请注明出处 一.先上一张图 二.解释 1. Metadata Servers (masters) ...

  2. springboot aop 自定义注解方式实现一套完善的日志记录(完整源码)

    https://www.cnblogs.com/wenjunwei/p/9639909.html https://blog.csdn.net/tyrant_800/article/details/78 ...

  3. Javascript this 的一些总结

    1.1.1 摘要 相信有C/C++.C#或Java等编程经验的各位,对于this关键字再熟悉不过了.由于Javascript是一种面向对象的编程语言,它和C/C++.C#或Java一样都包含this关 ...

  4. [Codeforces797F]Mice and Holes

    Problem n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离. Solution 用dp[i][j]表示前i个洞,进了前j个老鼠的最小代价 dp[i][j]=min(dp[i ...

  5. python全栈开发笔记---------基本数据类型

    基本数据类似包括: 字符串(str) 数字(int) 列表(list) 元祖(tuple) 字典(dict) 布尔值(bool) 字符串(引号): name = "我是某某某" n ...

  6. RabbitMQ 均衡调度(公平分发机制)

    均衡调度是针对Consumer来说的.现在有两个Consumer请求同一个队列的消息.RabbitMQ会将序号为奇数的消息发给第一个Consumer,会将序号为偶数的消息发送给第二个Consumer. ...

  7. JavaScript 操作DOM对象

    1)JavaScript  操作DOM對象 1.DOM:是Document  Object  Model 的缩写,及文档对象模型 2.DOM通常分为三类:DOM Core(核心).HTML-DOM 和 ...

  8. 网页设置下载apk

     APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Ja ...

  9. netcore 2.0 部署 到iis

    .net Core2.0应用程序发布window服务器报错容易错过的配置. 1.应用程序发布. 2.IIS上新建网站. 3.应用程序池选择无托管代码. 4.服务器上安装DotNetCore.1.0.2 ...

  10. 5.2 C++重载操作符的优先级

    参考:http://www.weixueyuan.net/view/6380.html 总结: 重载操作符不能改变操作符的优先级和语法特性. 重载操作符不能改变操作符的优先级和语法特性.例如上一节复数 ...