本套题没有什么数据结构题,图论题,唯一有价值的就是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. JBOSS禁用delete和put方法教程

    一.背景说明(与此节修复没多大关系可跳过) 今天应用报扫描出“启用不安全的HTTP方法”漏洞需要进行修复,看后边还有IIS的修复建议:一边不满怎么用IIS一边研究了具体操作半天,由于IIS不同版本操作 ...

  2. WinForm之窗体应用程序

    WinForm之窗体应用程序 基本简单数据库操作(增删改查) using System; using System.Collections.Generic; using System.Windows. ...

  3. mysql如何让自增id从某个位置开始设置方法

    一般情况下两种方式: 1.本地数据不需要的情况下直接情况表(尽量不使用

  4. mybatis 无法自动补全,没有获得dtd文件

    由于网络原因,eclipse无法下载到http://mybatis.org/dtd/mybatis-3-mapper.dtd,导致eclipse的编辑器无法自动补全标签. 解决办法:将dtd文件下载到 ...

  5. vue-router-4-编程式导航

    想要导航到不同的 URL,用 router.push 方法,会向 history 栈添加一个新的记录 <router-link> <==>router.push // 字符串 ...

  6. 用Python的导入csv、文本文件、Excel文件的数据

    使用read_csv函数导入CSV文件 read.csv函数语法 read_csv(file,encoding) 例子: Age,Name 22,wangwei 23,lixin 24,liqing ...

  7. Xilinx 7 series FPGA multiboot技术的使用(转)

    reference:https://www.cnblogs.com/chensimin1990/p/9067629.html 当升级程序有错误的时候,系统会启动golden bitstream 注意: ...

  8. idea 一些插件配置

    接触maven快2年了吧,对maven还是一知半解其实.得到了一些教训,就是少转牛角尖,多把握实际需要的东西,一口一口吃饭. 插件化很常见了.这里记录idea使用的jetty插件 和tomcat插件和 ...

  9. ubuntu apache ssl配置

    参考连接: http://blog.csdn.net/sky_qing/article/details/44303221 http://blog.sina.com.cn/s/blog_6ad62438 ...

  10. mvc Model验证总结及常用正则表达式

    本文属转载,来源: http://www.byywee.com/page/M0/S868/868615.html 关于Model验证官方资料: http://msdn.microsoft.com/zh ...