5385: 树的遍历 

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 22            Accepted:16

Description

给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。

Input

输入第一行给出一个正整数N(<=30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。

Output

在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。

Sample Input

7
2 3 1 5 7 6 4
1 2 3 4 5 6 7

Sample Output

4 1 6 3 5 7 2

如题意所述,我们可以直接得到其前序遍历结果,所以hash一下就好了,特别大了而且成链就写一个大数吧,hash一下就好的

#include <bits/stdc++.h>
using namespace std;
map<int,int>M;
int s[31],c[31],l;
void la(int l,int r,int st,int ed,int f)
{if(l<=r&&st<=ed){M[f]=c[ed];for(int i=l; i<=r; i++)if(c[ed]==s[i]){la(l,i-1,st,st+i-1-l,2*f+1),la(i+1,r,st+i-l,ed-1,2*f+2);return ;}}
}
int main()
{cin>>l;for(int i=0;i<l;i++)cin>>c[i];for(int i=0;i<l;i++)cin>>s[i];la(0,l-1,0,l-1,0);int f=0;for(auto X:M){if(f)cout<<" ";cout<<X.second,f=1;}return 0;
}

taozi的队列代码

#include<bits/stdc++.h>
using namespace std;
int post[1000],in[1000],Left[1000],Right[1000];
int n;
int build(int L1,int R1,int L2,int R2)
{if(L1>R1)return 0;int root=post[R1];int pos=L2;while(in[pos]!=root)pos++;int cnt=pos-L2;Left[root]=build(L1,L1+cnt-1,L2,pos-1);Right[root]=build(L1+cnt,R1-1,pos+1,R2);return root;
}
void level()
{queue<int>q;q.push(post[n]);int f=0;while(!q.empty()){int u=q.front();q.pop();if(!f)printf("%d",u),f=1;else printf(" %d",u);if(Left[u])q.push(Left[u]);if(Right[u])q.push(Right[u]);}
}
int main()
{cin>>n;for(int i=1;i<=n;i++)cin>>post[i];for(int i=1;i<=n;i++)cin>>in[i];build(1,n,1,n);level();return 0;
}

5445: 中位数 

时间限制(普通/Java):2000MS/6000MS     内存限制:250000KByte
总提交: 15            测试通过:2

描述

给定两个序列,都已经从小到大排序,求两个序列合并后的中位数。

所谓中位数是指:当排序后的序列元素个数是奇数时取中间值,否则去中间两个数的平均数。

你能想出O(log(m+n))复杂度的算法吗?

输入

多组数据。每组数据的:

第一行为两个整数n和m,(1<=n, m<=10000000)。

第二行由n个从小到大排序的整数。

第三行由m个从小到大排序的整数。

以EOF结束。

输出

输出中位数,保留2位小数。

样例输入

2 1
1 3
2
2 2
1 2
3 4

样例输出

提示

因本题输入数据规模较大,请使用类似以下代码输入一个整数(输入挂):

int Scan()

{

int res = 0, ch, flag = 0;

if((ch = getchar()) == '-')             //判断正负

flag = 1;

else if(ch >= '0' && ch <= '9')           //得到完整的数

res = ch - '0';

while((ch = getchar()) >= '0' && ch <= '9' )

res = res * 10 + ch - '0';

return flag ? -res : res;

}

枚举pos看他是第几个数,当然也会相等,所以这个还是特判一下的

为什么这样是可以的呢,因为你每个数在两个数组均会有一个位置的,我只要遍历每个数组就可以找到

mi代表当前位置,其实个数是mi+1

pos-1代表可以插入到的位置,前一个可能是相等,也可能是不等

#include<bits/stdc++.h>
using namespace std;
const int N=10000005;
int a[N],b[N],n,m;
long long L,R,zws;
int la()
{while(L<=R){int mi=(L+R)>>1;int pos=upper_bound(a,a+n,b[mi])-a;if(pos&&a[pos-1]==b[mi]){if(mi+pos==zws)return mi;}if(mi+pos+1<zws){if(mi==m-1)return -1;L=mi+1;}else if(mi+pos+1>zws){if(mi==0)return -1;R=mi-1;}else
        {return mi;}}return -1;
}
int lb()
{while(L<=R){int mi=(L+R)>>1;int pos=upper_bound(b,b+m,a[mi])-b;if(pos&&b[pos-1]==a[mi]){if(mi+pos==zws)return mi;}if(mi+pos+1<zws){if(mi==n-1)return -1;L=mi+1;}else if(mi+pos+1>zws){if(mi==0)return -1;R=mi-1;}else
        {return mi;}}return -1;
}
int Scan()
{int res = 0, ch, flag = 0;if((ch = getchar()) == '-')
flag = 1;else if(ch >= '0' && ch <= '9')
res = ch - '0';while((ch = getchar()) >= '0' && ch <= '9' )res = res * 10 + ch - '0';return flag ? -res : res;}int main()
{while(~scanf("%d%d",&n,&m)){for(int i=0; i<n; i++)a[i]=Scan();for(int i=0; i<m; i++)b[i]=Scan();L=0,R=m-1,zws=(n+m+1)/2;int t=la();if(t==-1)L=0,R=n-1,t=lb(),t=a[t];else t=b[t];if((n+m)%2==0){zws++;L=0,R=m-1;int t1=la();if(t1==-1)L=0,R=n-1,t1=lb(),t1=a[t1];else t1=b[t1];t+=t1;}else t+=t;printf("%.2f\n",t/2.);}return 0;
}

5201: 数字游戏 

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 125            Accepted:17

Description

栋栋正在和同学们玩一个数字游戏。
游戏的规则是这样的:栋栋和同学们一共n个人围坐在一圈。栋栋首先说出数字1。接下来,坐在栋栋左手边的同学要说下一个数字2。再下面的一个同学要从上一个同学说的数字往下数两个数说出来,也就是说4。下一个同学要往下数三个数,说7。依次类推。
为了使数字不至于太大,栋栋和同学们约定,当在心中数到 k-1 时,下一个数字从0开始数。例如,当k=13时,栋栋和同学们报出的前几个数依次为:
  1, 2, 4, 7, 11, 3, 9, 3, 11, 7。
游戏进行了一会儿,栋栋想知道,到目前为止,他所有说出的数字的总和是多少。

Input

输入的第一行包含三个整数 n,k,T,其中 n 和 k 的意义如上面所述,T 表示到目前为止栋栋一共说出的数字个数。

Output

输出一行,包含一个整数,表示栋栋说出所有数的和。

Sample Input

Sample Output

3 13 3

Hint

17

样例说明

  栋栋说出的数依次为1, 7, 9,和为17。

数据规模和约定

  1 < n,k,T < 1,000,000;

可以枚举要加的值

#include<bits/stdc++.h>
using namespace std;int main()
{long long n,k,T,res=0,last=1;cin>>n>>k>>T;for(int i=1;i<T;i++){res+=(last+(2*i*n-n+1)*n/2)%k;last=(last+(2*i*n-n+1)*n/2)%k;}cout<<res+1;return 0;
}

5202: 网络寻路 

时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte
总提交: 1            测试通过:1

描述

X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。

源地址和目标地址可以相同,但中间节点必须不同。

如下图所示的网络。

1 -> 2 -> 3 -> 1 是允许的

1 -> 2 -> 1 -> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。

输入

输入数据的第一行为两个整数N M,分别表示节点个数和连接线路的条数(1<=N<=10000; 0<=M<=100000)。

接下去有M行,每行为两个整数 u 和 v,表示节点u 和 v 联通(1<=u,v<=N , u!=v)。

输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。

输出

输出一个整数,表示满足要求的路径条数。

样例输入

3 3
1 2
2 3
1 3

样例输出

6

提示

样例输入2

4 4
1 2
2 3
3 1
1 4

样例输出2

10

可以dfs去枚举,也就是去枚举两边的点让他们不形成环

但是注意目的地可以和源地址相同,那么合法的就有以下两种情况

case1

case2

和当前节点的度有关,即这条边除了这条路带来的度的乘积

#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int d[N],u[N],v[N],n,m;
int main()
{long long ans=0;scanf("%d%d",&n,&m);for(int i=0; i<m; i++)scanf("%d%d",&u[i],&v[i]),d[u[i]]++,d[v[i]]++;for(int i=0; i<m; i++)if(d[u[i]]>1&&d[v[i]]>1)ans+=(d[u[i]]-1)*1LL*(d[v[i]]-1)*2;printf("%I64d\n",ans);return 0;
}

5204: 小朋友排队 

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 18            Accepted:2

Description

n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

Input

输入的第一行包含一个整数n,表示小朋友的个数。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。

Output

输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

Sample Input

3
3 2 1

Sample Output

9

Hint

样例说明

  首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。

数据规模和约定

  对于10%的数据, 1<=n<=10;
  对于30%的数据, 1<=n<=1000;
  对于50%的数据, 1<=n<=10000;
  对于100%的数据,1<=n<=100000,0<=Hi<=1000000。

前置技能逆序对,即交换相邻两个数字的最小次数

再考虑这个问题,就是问你一个数要交换几次,这个自己可以推一下

其实就是把数倒过来正序对的个数比如 3 2 1逆序对贡献是0 1 2

倒过来1 2 3正序对贡献0 1 2,即0+2 1+1 2+0所求次数

他卡我其他求逆序对的方式,只能归并排序过的

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int w[N],sum[N],n;
struct T
{int x,num;
} a[N],T[N];
void la(int l,int r)
{if(r-l==1)return;int m=l+r>>1,tm=l+r>>1,tl=l,i=l;la(l,m),la(m,r);while(tl<m||tm<r){if(tm>=r||(tl<m&&a[tl].x<=a[tm].x))T[i++]=a[tl++],T[i-1].num+=tm-m;elseT[i++]=a[tm++],T[i-1].num+=m-tl;}for(int i=l; i<r; i++)a[i]=T[i];
}
int main()
{scanf("%d",&n);for(int i=0; i<n; i++)scanf("%d",&a[i].x),a[i].num=0;la(0,n);__int64 ans=0;for(int i=0; i<n; i++)ans+=a[i].num*1LL*(a[i].num+1)/2;printf("%I64d",ans);return 0;
}

5205: 最大子阵 

Time Limit(Common/Java):4000MS/12000MS     Memory Limit:65536KByte
Total Submit: 21            Accepted:8

Description

给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。

Input

输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。

Output

输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。

Sample Input

3 3
-1 -4 3
3 4 -1
-5 -2 8

Sample Output

10

Hint

样例说明

  取最后一列,和为10。

数据规模和约定

  对于50%的数据,1<=n, m<=50;
  对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。

想起来了要用最大字段和,但是这个dp过程还是不好想的

你可以对行或列做下前缀和,然后再求下最大字段和

基于行的dp

#include<stdio.h>
const int N=505;
int r[N][N];
int main()
{int n,m,x;scanf("%d%d",&n,&m);for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)scanf("%d",&x),r[i][j]=r[i-1][j]+x;int ma=x,t;for(int i=1; i<=n; i++)for(int j=i; j<=n; j++){t=0;for(int k=1; k<=m; k++){t+=r[j][k]-r[i-1][k];if(t>ma)ma=t;if(t<0)t=0;}}printf("%d",ma);return 0;
}

数据分布不均匀,基于列的dp跑起来比较慢

#include<stdio.h>
const int N=505;
int r[N][N];
int main()
{int n,m,x;scanf("%d%d",&n,&m);for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)scanf("%d",&x),r[i][j]=r[i][j-1]+x;int ma=x,t;for(int i=1; i<=m; i++)for(int j=i; j<=m; j++){t=0;for(int k=1; k<=n; k++){t+=r[k][j]-r[k][i-1];if(t>ma)ma=t;if(t<0)t=0;}}printf("%d",ma);return 0;
}

5206: 约数倍数选卡片 

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 1            Accepted:1

Description

闲暇时,福尔摩斯和华生玩一个游戏:
在N张卡片上写有N个整数。两人轮流拿走一张卡片。要求下一个人拿的数字一定是前一个人拿的数字的约数或倍数。例如,某次福尔摩斯拿走的卡片上写着数字“6”,则接下来华生可以拿的数字包括:
  1,2,3, 6,12,18,24 ....
当轮到某一方拿卡片时,没有满足要求的卡片可选,则该方为输方。
请你利用计算机的优势计算一下,在已知所有卡片上的数字和可选哪些数字的条件下,怎样选择才能保证必胜!
当选多个数字都可以必胜时,输出其中最小的数字。如果无论如何都会输,则输出-1。

Input

输入数据为2行。第一行是若干空格分开的整数(每个整数介于1~100间),表示当前剩余的所有卡片。
第二行也是若干空格分开的整数,表示可以选的数字。当然,第二行的数字必须完全包含在第一行的数字中。

Output

程序则输出必胜的招法!!

Sample Input

2 3 6
3 6

Sample Output

3

Hint

样例输入2

1 2 2 3 3 4 5
3 4 5

样例输出2

4

博弈题目,但是题目数据应该不是很多,直接dfs就过了

大概思路是这样的,因为我要选择必胜,即某个选择可以导致对手出现必败态

还要输出最小的数字,所以需要对b数组进行排序

然后需要预处理一下一个数的约数和倍数,假如这个数量级很大了,貌似就很难过了,倍数还有约数要很好的处理下,可以把有些数组直接赋值过去

#include<bits/stdc++.h>
using namespace std;
#define dbg(x) cout<<#x<<" = "<< (x)<< endl
const int N=105;
int num[N];
vector<int> b,f[N];
int dfs(int x)
{for(int i=f[x].size()-1; i>=0; i--){int pp=f[x][i],t;if(num[pp]){num[pp]--,t=dfs(pp),num[pp]++;if(t)return 0;}}return 1;
}
void la()
{for(auto X:b){if(num[X]){num[X]--;if(dfs(X)){cout<<X;return;}num[X]++;}}cout<<-1;
}
int main()
{int x;string s;getline(cin,s);stringstream ss(s);while(ss>>x)num[x]++;getline(cin,s);stringstream st(s);while(st>>x)b.push_back(x);sort(b.begin(),b.end());for(int i=1; i<N ; i++)if(num[i])for(int j=1; j<N ; j++)if(num[j]&&(i%j==0||j%i==0))f[i].push_back(j);la();return 0;
}

5200: 买不到的数目 

Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
Total Submit: 57            Accepted:43

Description

小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。

小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。

你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

Input

两个正整数,表示每种包装中糖的颗数(都不多于1000)

Output

一个正整数,表示最大不能买到的糖数。

如果这个数不存在,则输出-1。

Sample Input

4 7

Sample Output

17

Hint

样例输入2

3 5

样例输出2

7

题目不严谨,因为有1的时候是不存在这个数的,而且你很快会发现只有互质的时候才存在,否则是不存在的

但是是一个很好的数论

证明以下2个命题
1. (x-1)(y-1)-1 不能被表示为 ax+by的形式
2. 大于等于(x-1)(y-1)都能被表示为 ax+by的形式
当时题目数据是满足 x>1,y>1,gcd(x,y)==1的,现在可能改了hhh
#include <stdio.h>
int main()
{int a,b;scanf("%d%d",&a,&b);printf("%d",a*b-a-b);
}

转载于:https://www.cnblogs.com/BobHuang/p/8980104.html

2018集训队日常训练1相关推荐

  1. codeforces日常训练 C. Cutting Out - 二分搜索答案

    codeforces日常训练 C. Cutting Out - 二分搜索答案 题干 You are given an array s consisting of n integers. You hav ...

  2. 「日常训练」Common Subexpression Elimination(UVa-12219)

    今天做的题目就是抱佛脚2333 懂的都懂. 这条题目干了好几天,最后还是参考别人的代码敲出来了,但是自己独立思考了两天多,还是有收获的. 思路分析 做这条题我是先按照之前的那条题目(The SetSt ...

  3. 「日常训练」 Mike and Fun (CFR305D2B)

    题意(CodeForces 548B) 每次对01矩阵中的一位取反,问每次操作后,单列中最长连续1的长度. 分析 非常非常简单,但是我当时训练的时候WA了四次...无力吐槽了,人间 不值得.jpg 代 ...

  4. 2018年日常小计汇总

    2018年 从2018-10-06开始记录 十二月 2018-12-27 解析nginx日志,实时了解服务器的情况(类似于top) https://github.com/lebinh/ngxtop N ...

  5. 动规日常训练题解 难度普及+

    9.6 动规训练  题解 ----Frosty_Jackal 定义Dpmax[i][j] 表示l~r之间最大的得分,由题意得拆环为链,将1~n的枚举范围扩大到1~2*n ,外层枚举区间长,内层枚举l, ...

  6. GXNU竞赛集训队第一次训练题解

    2022/3/19训练题单 1352B 1512D 1368B 1542B 1399D 1372C 1400C 1352F 282C 916C 980B 214B B. Same Parity Sum ...

  7. 「日常训练」Bad Luck Island(Codeforces Round 301 Div.2 D)

    题意与分析(CodeForces 540D) 是一道概率dp题. 不过我没把它当dp做... 我就是凭着概率的直觉写的,还好这题不算难. 这题的重点在于考虑概率:他们喜相逢的概率是多少?考虑超几何分布 ...

  8. 2018提高组训练Day2

    A 算法 1 对于每组询问,暴力的算出每个二次函数的取值. 时间复杂度 \(O(nq)\).期望得分 \(20\) 分. 算法 2 当 \(x>0\) 时,要求 \(a_ix^2+b_ix\) ...

  9. 「日常训练」Skills(Codeforce Round #339 Div.2 D)

    题意(CodeForces 614D) 每个人有\(n(n\le 10^5)\)个技能,技能等级都在\([0,10^9]\)的范围,每个技能有一个当前等级,所有技能的最高等级都为A.一个人的力量被记做 ...

最新文章

  1. modelsim中仿真波形设置的保存
  2. ReentrantLock实现原理深入探究
  3. 数字化专业人才短缺,企业亟待组建培养体系
  4. LeetCode 1942. 最小未被占据椅子的编号(set)
  5. 使用indexOf()算出长字符串中包含多少个短字符串
  6. MySQL高可用--MGR入门(2)组复制监控常用相关表
  7. [SCOI2005][BZOJ 1084]最大子矩阵
  8. mysql查询最接近的记录
  9. 华云数据:以信创云构筑自主创新长城之基
  10. windows xp sp3 下载地址
  11. Ubuntu好用的截图工具
  12. Massive MIMO中正交导频pilot序列的MATLAB生成方法
  13. 模拟一个简单的购房商贷月供计算器
  14. 基于微信小程序社区疫情防控系统
  15. Android APP的签名
  16. 【音视频处理】码率、帧率越高越清晰?分辨率、像素、dpi之间是什么关系?码率的真实作用,I帧、B帧、P帧是什么
  17. ASR技术和TTS技术含义及区别
  18. hive只复制表结构不复制表数据
  19. Mysql高级——索引篇
  20. gevent 实现网易云音乐歌曲下载

热门文章

  1. ORACLE RAC+DG 硬件配置
  2. category android:name=android.intent.category.DEFAULT / 惹的祸
  3. v8学习笔记(五) 编译过程
  4. Python架构(二)
  5. Gitlab的CI/CD初尝试
  6. OpenCV+yolov3实现目标检测(C++,Python)
  7. 软件设计模式—依赖注入
  8. [2019HDU多校第一场][HDU 6590][M. Code]
  9. P1772 [ZJOI2006]物流运输 最短路+DP
  10. Django的静态资源