18708 最大子段和
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定

Description
一个整数序列,选出其中连续且非空的一段使得这段和最大。

输入格式
第一行是一个正整数N,表示了序列的长度(0=<N<=200000)。
第二行包含N个绝对值不大于10000的整数ai。
输出格式
一个整数,为最大的子段和。子段的最小长度为1。数据确保结果在类型int范围内。
输入样例
7
2 -4 3 -1 2 -4 3
输出样例
4
提示
【样例说明】

2,-4,3,-1,2,-4,3中,最大的子段和为4,该子段为第三元素至第五元素,即3,-1,2。

题解:典型的动态规划或者分治。
分治法(难)

#include<iostream>
#include<cstdio>
using namespace std;
int num[200010];
int f(int left,int right)
{//printf("%d %d\n",left,right);if(right==left+1){return max(num[left],max(num[right],num[left]+num[right]));}else if(left==right){return num[left];}//过中点int mid=(left+right)/2;int mmax=num[mid],temp=num[mid];//从中点向左延伸,寻找连续子序列最大值for(int i=mid-1;i>=left;i--){temp+=num[i];mmax=max(mmax,temp);}temp=mmax;for(int i=mid+1;i<=right;i++){temp+=num[i];mmax=max(mmax,temp);}int mmax1=f(left,mid-1);//注意是mid-1即不过中点int mmax2=f(mid+1,right);//printf("%d %d %d\n",mmax1,mmax2,mmax);//printf("*%d %d\n",left,right);return max(max(mmax1,mmax2),mmax);
}
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}long long mmax=f(1,n);cout<<mmax<<endl;return 0;
}

动态规划法

#include<iostream>
#include<cstdio>
using namespace std;
long long dp[200010];
int num[200010];
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}long long mmax=-20000;for(int i=1;i<=n;i++){if(dp[i-1]>0){dp[i]=num[i]+dp[i-1];}else dp[i]=num[i];if(dp[i]>mmax){mmax=dp[i];}}cout<<mmax<<endl;return 0;
}

18709 魔法
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
农夫约翰的奶牛场有很多奶牛,奶牛有黑白两种颜色。现在奶牛们排成整齐的一列去参加镇上的游行活动。
约翰希望白色奶牛都排在前面,黑色的奶牛都排在后面。但现在队列中奶牛的颜色是混乱的,并且奶牛们都不愿意改变位置。
幸运的是,约翰有一根魔法棒,每挥舞一次魔法棒就可以改变一头奶牛的颜色。
请问,约翰至少要挥舞多少次魔法棒,才能将队列改成他希望的状态。注意,可以将所有的奶牛都变成白色,或者都变成黑色。

输入格式
第一行一个正整数n,表示奶牛的头数。(1<=n<=200000)。
第二行n个正整数,均为1或2,1表示白色奶牛,2表示黑色奶牛。
输出格式
一个正整数,表示挥舞魔法棒的最少次数。
输入样例
7
2 2 1 1 1 2 1
输出样例
3
提示
可以把1和2号奶牛变成1,7号奶牛变成2,或者全部奶牛变成1,最少需要3次。

题解:我们可以o(n)枚举白牛与黑牛的交界处,这N种情况的最值就是答案啦。那枚举完,假设第一头黑牛的位置是pos,我们用sum黑表示黑牛前n项和,sum白表示白牛。那么就有变化次数就是=sum黑[pos-1]+sum白[n]-sum[pos-1]。

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int sum[200010][2];//0表示白,1表示黑
int main ()
{int n;scanf("%d",&n);int num;for(int i=1;i<=n;i++){scanf("%d",&num);sum[i][0]=sum[i-1][0];sum[i][1]=sum[i-1][1];if(num==1){sum[i][0]=sum[i-1][0]+1;}else{sum[i][1]=sum[i-1][1]+1;}}int mmax=1000000;for(int i=1;i<=n;i++){int temp1=sum[i][1]-sum[i][0]+sum[n][0];mmax=min(temp1,mmax);}printf("%d\n",mmax);return 0;
}

18711 字符串去重
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
一个完全由小写字母组成的长度为n的字符串,现在要求你去除所有重复的字母,并将剩下的字母按从小到大的次序输出。
如输入baaadccaab,输出abcd。

输入格式
第一行一个整数n,表示字符串长度(0<=n<=100000)。
第二行一个字符串。
输出格式
去除所有重复的字母,并将剩下的字母按从小到大的次序输出。
输入样例
10
baaadccaab
输出样例
abcd

题解:直接对出现的字符进行标记就可以了

#include<iostream>
#include<cmath>
#include<cstdio>
#include<set>
#include<string>
#include<cstring>
using namespace std;
char s[100010];
int book[27];
int main ()
{int n;scanf("%d",&n);getchar();gets(s);for(int i=0;i<n;i++){book[s[i]-96]=1;}for(int i=1;i<=26;i++){if(book[i])printf("%c",96+i);}return 0;
}

18710 统计不同数字的个数(升级版)
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
由键盘输入n个整数,统计不同数字的个数(0<=n<=200000)。

PS:此题目和1040仅数据规模不同。但如果使用如下O(n2)级别的算法必然会超时。
int main()
{
int a[21],i,c=0,b,j;
for(i=1;i<=20;i++)
{
cin>>b;
for(j=1;j<=c;j++)
{
if(b==a[j])
{
break;
}
}
if(j>c)
{
a[c+1]=b;
c++;
}
}
cout<<c;
return 0;
}

输入格式
第一行一个整数n(0<=n<=200000)。
第二行n个整数a1,a2…an,(0<=ai<=200000)。
输出格式
仅一行,不同数字的个数。
输入样例
70 5 14 22 19 2 99 67 13 66 5 93 44 38 22 11 39 22 33 11
输出样例
16

题解:因为整数范围很小,直接开一个200000的数组对出现的数字标记

#include<iostream>
#include<cmath>
#include<cstdio>
#include<set>
#include<string>
#include<cstring>
using namespace std;
int book[200010];
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){int num;scanf("%d",&num);book[num]=1;}int ans=0;for(int i=0;i<=200000;i++){if(book[i]){ans++;}}cout<<ans<<endl;return 0;
}

18063 圈中的游戏
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: G++;GCC;VC
Description
有n个人围成一圈,从第1个人开始报数1、2、3,每报到3的人退出圈子。编程使用链表找出最后留下的人。

输入格式
输入一个数n,1000000>=n>0
输出格式
输出最后留下的人的编号
输入样例
3
输出样例
2

题解:直接数组来模拟

#include<iostream>
#include<cmath>
#include<cstdio>
#include<set>
#include<string>
#include<cstring>
using namespace std;
int book[200010];
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){int num;scanf("%d",&num);book[num]=1;}int ans=0;for(int i=0;i<=200000;i++){if(book[i]){ans++;}}cout<<ans<<endl;return 0;
}

18712 组合问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
找出从自然数1、2、……、m中任取k个数的所有组合,组合中字典序大的先输出。
例如m=5,k=3,应输出
5 4 3
5 4 2
5 4 1
5 3 2
5 3 1
5 2 1
4 3 2
4 2 1
3 2 1

输入格式
两个整数m和k,(1<=k<=m<=10)
输出格式
按字典序输出所有组合
输入样例
5 2
输出样例
5 4
5 3
5 2
5 1
4 3
4 2
4 1
3 2
3 1
2 1

题解:dfs进入一次回溯时,前面已经出现的数字标记,然后按顺序找到没标记的数字就可以了

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<stack>
using namespace std;
int book[12];
int box[12];
int n,k;
void dfs(int step)
{if(step==k+1){for(int i=1;i<=k;i++){printf("%d ",box[i]);}printf("\n");return;}for(int i=n;i>=1;i--){if(!book[i]&&i<box[step-1]){box[step]=i;book[i]=1;dfs(step+1);book[i]=0;}}return;
}
int main ()
{scanf("%d%d",&n,&k);box[0]=n+1;dfs(1);return 0;
}

18713 整数的分解
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
输出一个正整数n的分解形式。例如,当n=4时,输出:
4=4
4=3+1
4=2+2
4=2+1+1
4=1+1+1+1
共计 5 种形式。
当n=7时,共有15种形式。
当n=10时,共有42种形式。

输入格式
一个整数n(1<=n<=10)。
输出格式
n的全部分解形式,注意分解式中数字值大的排在前面,如第一个数字值相同,那么比较第二个数字。
输入样例
4
输出样例
4=4
4=3+1
4=2+2
4=2+1+1
4=1+1+1+1

题解:很明显又是一次dfs的题,把每个等式的第一个式子枚举出来,很明显dfs里面放一个for对吧,就好比数字4,那他有4个等式,每个等式第一个数字分别是4,3,2,1,比如我们拿第二个等式,枚举完3后,那4-3剩下的部分就继续dfs,让他继续分解,不过要注意后面的分解出来的数比前面的要小。

#include<iostream>
#include<cstdio>
using namespace std;
int book[12];
int num;
void dfs(int n,int pri)//pri表示前面的数值
{if(n<=0){printf("%d",num);int pos=1;for(int i=num;i>=0;i--){for(int j=1;j<=book[i];j++){if(pos){printf("=");pos=0;}else printf("+");printf("%d",i);}}printf("\n");return;}for(int i=n;i>=1;i--){if(i>pri){continue;}book[i]++;dfs(n-i,i);book[i]--;}return;
}
int main ()
{scanf("%d",&num);dfs(num,12);return 0;
}

18714 迷宫问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
迷宫是一个n*m的矩阵,玩家需要迷宫入口(坐标1,1)出发,寻找路径走到出口(n,m)。
请判断玩家能否从迷宫中走出。

输入格式
第一行两个整数n和m,代表n行m列。(1<=n,m<=10)
下面n行每行m个字符,0代表可以通行,1代表不可以通行。

输出格式
如果能从迷宫走出,输出yes,否则输出no。
输入样例
8 8
00100010
00100010
00001100
01110000
00010000
01000100
01110110
00001000
输出样例
yes
提示
样例数据即为图片迷宫

题解:直接dfs或者bfs模板

#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;
char mmap1[20][20];
int mmap[20][20];
int book[20][20];
int next1[4][2]={{1,0},{0,1},{-1,0},{0,-1} };
int main ()
{queue<pair<int,int> > que;int n,m;scanf("%d%d",&n,&m);getchar();for(int i=0;i<n;i++){gets(mmap1[i]);}for(int i=0;i<n;i++){for(int j=0;j<m;j++){mmap[i+1][j+1]=mmap1[i][j]-'0';}}que.push(make_pair(1,1));book[1][1]=1;while(!que.empty()){if(que.front().first==n&&que.front().second==m){printf("yes");return 0;}int x=que.front().first,y=que.front().second;// printf("%d %d\n",x,y);for(int i=0;i<4;i++){int x1=x+next1[i][0],y1=y+next1[i][1];if(x1<1||x1>n||y1<1||y1>n||book[x1][y1]||mmap[x1][y1]){continue;}else{book[x1][y1]=1;que.push(make_pair(x1,y1));}}que.pop();}printf("no");return 0;
}

18715 出栈序列
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
一种简洁的栈定义方法如下
int st[1000],top=0;//以top作为栈顶指针,top==0为空栈
st[top++]=x;//把x入栈,栈顶指针+1
top–;//出栈
现在有一个1-n的排列,入栈序列已知,请给出字典序最大的出栈序列。

输入格式
第一行一个整数n。(1<=n<=100)
第二行n个整数,数据确保为1-n的排列。
输出格式
输出n个整数,既字典序最大的出栈序列。
输入样例
5
1 2 4 5 3
输出样例
5 4 3 2 1

题解:直接模拟题来做就行,先第一个元素入栈,然后在没入栈的数组里面找到最大值,比较一下最大值大还是栈顶元素大,栈顶大的话就出栈然后继续比较,直到数组里面的元素最大值比栈顶大,那就可以整段放入栈里面,然后最大值放入答案序列,一直循环往复,直到外面数组元素全空,然后把栈里面的元素输出。

#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
int num[110];
int book[110];
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}int mmax=n;stack<int> sck;for(int i=1;i<=n;i++){//printf("\nmmax=%d \n",mmax);if(!sck.empty()&&sck.top()>mmax){printf("%d ",sck.top());sck.pop();i--;continue;}if(book[num[i]]){continue;}if(num[i]==mmax){book[mmax]=1;printf("%d ",num[i]);for(int j=mmax-1;j>=1;j--){if(!book[j]){mmax=j;break;}}}else{sck.push(num[i]);book[num[i]]=1;}}while(!sck.empty()){printf("%d ",sck.top());sck.pop();}return 0;
}

18717 舞伴问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
假设在周末舞会上,男士们和女士们进入舞厅时,各自排成一队。
跳舞开始时,依次从男队和女队的队头上各出一人配成舞伴。
规定每个舞曲能有一对跳舞者。若两队初始人数不相同,则较长的那一队中未配对者等待下一轮舞曲。
现要求写一个程序,模拟上述舞伴配对问题。

输入格式
第一行两个正整数n和m,分别代表男队和女队的人数,规定男队编号从1至n,女队编号从1至m。
第二行输入一个正整数k,表示第k对舞伴。(1<=n,m,k<=100)
输出格式
输出第k对舞伴的两个编号。
输入样例
4 6
7
输出样例
3 1

题解:就是取模运算

#include<iostream>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
int main ()
{int n,m;int k;scanf("%d%d%d",&n,&m,&k);if(k%n==0){printf("%d ",n);}else printf("%d ",k%n);if(k%m==0){printf("%d ",m);}else printf("%d ",k%m);return 0;
}

18720 迷宫问题 (最短路径)
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定
Description
迷宫是一个n*m的矩阵,玩家需要迷宫入口(坐标1,1)出发,寻找路径走到出口(n,m)。
请判断玩家能否从迷宫中走出,如果能走出迷宫输出,输出最短的路径长度,否则输出-1。

输入格式
第一行两个整数n和m,代表n行m列。(1<=n,m<=10)
下面n行每行m个字符,0代表可以通行,1代表不可以通行。
输出格式
如果能从迷宫走出,输出最短的路径长度,否则输出-1。
输入样例
8 8
00100010
00100010
00001100
01110000
00010000
01000100
01110110
00001000
输出样例
16

题解:bfs

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
char s[12][12];
int d[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
int tags[12][12];
struct tp
{int x;int y;int step;
};
int main ()
{int n,m;scanf("%d%d",&n,&m);for(int i=0;i<n;i++){scanf("%s",s[i]);}queue<struct tp> que;struct tp data;data.x=0;data.y=0;data.step=0;que.push(data);tags[0][0]=1;while(!que.empty()){if(que.front().x==n-1&&que.front().y==m-1){printf("%d\n",que.front().step);return 0;}for(int i=0;i<4;i++){int x=que.front().x+d[i][0];int y=que.front().y+d[i][1];int step=que.front().step+1;if(x<0||y<0||x>=n||y>=m||s[x][y]=='1'||tags[x][y]==1){continue;}tags[x][y]=1;data.x=x;data.y=y;data.step=step;que.push(data);}que.pop();}printf("-1\n");
}

18718 航行
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
银河帝国正走向覆亡。为保留文明的种子,你需要驾驶飞船将一批“颛家”从帝国首都护送至银河边缘的基地。
现在已知航线是一条直线,帝国首都为起点(坐标0),基地为终点(坐标L),在这条航线上有N个空间站可以补充飞船的能源。
第i个空间站的坐标为ai,飞船停靠在第i个空间站必须花费bi个银河币,同时让你的飞船能量恢复为最大值M。
出发前飞船的能量是满额的M,每一点能量都可以让飞船航行一个坐标单位。

现在你已经通过募捐(榨篇)获得了S个银河币,请计算下飞船能否到达基地。

输入格式
第一行输入四个个数字N,L,M,S;(1<=N<=200) (1<=L<=20000) (1<=M<=20000) (0<=S<=20000)
接下来N行,每行输入两个数字,ai,bi (0<=ai<=L) (0<=bi<=20000)
输出格式
仅一行,如果能到达基地,输出Yes,否则输出No
输入样例
1 10000 5000 20000
5000 20000
输出样例
Yes

题解:直接dfs每个点,都有两个选择,走与不走就可以了

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,len,eney,money;
struct node
{int fist,sec;
}data[100];//距离,消耗
int dfs(int s,int pos,int i)//钱,坐标,数组位置
{//printf("%d %d %d\n",s,pos,i);if(i>n||s<0)return 0;if(pos+eney>=len) return 1;for(int j=i+1;j<=n;j++){if(pos+eney<data[j].fist){break;}if(dfs(s,pos,j)||dfs(s-data[j].sec,pos+data[j].fist,j)){return 1;}}return 0;
}
bool cmp(struct node a,struct node b)
{return a.fist<b.fist;
}
int main ()
{scanf("%d%d%d%d",&n,&len,&eney,&money);for(int i=1;i<=n;i++){scanf("%d%d",&data[i].fist,&data[i].sec);}sort(data+1,data+1+n,cmp);if(dfs(money,0,0)){printf("Yes\n");}else printf("No\n");return 0;
}

18719 填涂颜色
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
由数字0组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向。
现要求把闭合圈内的所有空间都填写成2.例如:6×6的方阵(n=6),涂色前和涂色后的方阵如下:
涂色前:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
涂色后:
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

输入格式
每组测试数据第一行一个整数n(1≤n≤30)
接下来n行,由0和1组成的n×n的方阵。
方阵内只有一个闭合圈,圈内至少有一个0。
输出格式
已经填好数字2的完整方阵。
输入样例
6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1
输出样例
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

题解:因为一个封闭的0,他往四周走一定会在四个方向都碰到1,而不是碰到墙壁,然后直接对于每个数字进行验证就好

#include<iostream>
#include<cstdio>
using namespace std;
int mmap[50][50];
int n;
int d[5][2]={{0,0},{1,0},{-1,0},{0,1},{0,-1}};
int f(int i,int j)
{int x=i,y=j;int pos=1;for(int k=1;k<=4;k++){x=i;y=j;while(mmap[x][y]!=1&&x>0&&x<=n&&y>0&&y<=n){//printf("%d %d %d\n",x,y,k);x=x+d[k][0],y=y+d[k][1];}if(x>0&&x<=n&&y>0&&y<=n){continue;}else{pos=0;break;}}return pos;
}
int main ()
{scanf("%d",&n);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){scanf("%d",&mmap[i][j]);}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(mmap[i][j]==0&&f(i,j)){mmap[i][j]=2;}}}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){printf("%d ",mmap[i][j]);}printf("\n");}return 0;
}

18722 稀疏矩阵的运算
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
稀疏矩阵的压缩存储原则:只存矩阵的行列数和每个非零元的行列下标及其值。
例如下图的矩阵M由行列数(6,7)和三元组表{(1,2,12), (1,3,9), (3,1,-3),(3,6,14),(4,3,24),(5,2,18), (6,1,15), (6,4,-7) }唯一确定。
问题描述:已知一个稀疏矩阵的三元组表,使用快速转置算法求其转置矩阵的三元组表,三元组表要按行优先的方式存储。

输入格式
第一行三个整数n,m,k。n,m代表矩阵A的行列数(0<=n,m<=1000000),k为三元组表中元素的个数。
此后为k行,每行3个整数a,b,c,分别代表元素的行号,列号和值。数据确保按行优先给出。(0<=k<=10000)
输出格式
输出为k行,即转置矩阵的三元组表,三元组表要按行优先显示。
输入样例
6 7 8
1 2 12
1 3 9
3 1 -3
3 6 14
4 3 24
5 2 18
6 1 15
6 4 -7
输出样例
1 3 -3
1 6 15
2 1 12
2 5 18
3 1 9
3 4 24
4 6 -7
6 3 14

题解:题目很高深的样子,其实无非就是存一下数据

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{int x,y,num;
}data[10010];
bool cmp(struct node a,struct node b)
{if(a.x==b.x){return a.y<b.y;}else return a.x<b.x;
}
int main ()
{int n,m,k;scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=k;i++){scanf("%d%d%d",&data[i].y,&data[i].x,&data[i].num);}sort(data+1,data+1+k,cmp);for(int i=1;i<=k;i++){printf("%d %d %d\n",data[i].x,data[i].y,data[i].num);}return 0;
}

18724 二叉树的遍历运算
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
二叉树的三种遍历都可以通过递归实现。
如果我们知道一棵二叉树的先序和中序序列,可以用递归的方法求后序遍历序列。

输入格式
两行,第一行一个字符串,表示树的先序遍历,第二行一个字符串,表示树的中序遍历。树的结点一律用小写字母表示。
输出格式
一个字符串,树的后序序列。
输入样例
abcde
bcade

输出样例
cbeda

题解:根据特点来写递归就可以了,串a的第一个字母是顶点,然后串b就是找到顶点然后顶点左边是左子树右边是右子树,这样子我们对于子树我们是已经新的小串b,但是不知道小串a所以不能继续递归,其实小串a的长度其实等于小串b的长度,这样我们直接从大串a里面找特定长度的那一段就好了。

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
void f(string a,string b)
{//cout<<a<<endl<<b<<endl;if(a.size()<=0){return;}int pos;for(int i=0;i<int(b.size());i++){if(a[0]==b[i]){pos=i;break;}}//找到顶点//cout<<pos<<endl;string la,lb,ra,rb;for(int i=0;i<pos;i++){lb+=b[i];}for(int i=1;i<=pos;i++){la+=a[i];}for(int i=pos+1;i<int(b.size());i++){rb+=b[i];ra+=a[i];}f(la,lb);f(ra,rb);cout<<a[0];return;
}
int main ()
{string a,b;cin>>a>>b;f(a,b);return 0;
}

17263 计算二叉树的第k层中所有叶子结点个数
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC

Description
二叉链表表示的二叉树:按先序次序输入二叉树中结点的值,’#'字符表示空树,构造二叉链表表示的二叉树T(该二叉树中的结点为单个字符并且无值重复的结点),
编写算法完成:计算二叉树的第k层中所有叶子结点个数,根结点为第1层,根结点的孩子结点为第2层,依次类推。
#include “stdio.h”
#include “malloc.h”
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

Status CreateBiTree(BiTree &T) { // 算法6.4
// 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
// 构造二叉链表表示的二叉树T。
char ch;
scanf("%c",&ch);
if (ch==’#’) T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
________________________ // 生成根结点
_______________________ // 构造左子树
_________________________ // 构造右子树
}
return OK;
} // CreateBiTree

int main() //主函数
{
//补充代码
}//main

输入格式
第一行输入先序次序二叉树中结点
第二行输入层次k
输出格式
第一行输出该二叉树的第k层中所有叶子结点个数
输入样例
ABC###D##
2
输出样例
1

题解:模拟题

#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int  Status;
typedef char  ElemType;
typedef struct BiTNode{ElemType data;struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;Status CreateBiTree(BiTree &T) {  // 算法6.4// 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,// 构造二叉链表表示的二叉树T。char ch;scanf("%c",&ch);if (ch=='#') T = NULL;else {if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;T->data=ch; // 生成根结点CreateBiTree(T->lchild);  // 构造左子树CreateBiTree(T->rchild); // 构造右子树}return OK;
} // CreateBiTree
int f(BiTree &t,int i,int k)
{if(t==NULL){return 0;}else if(i==k){if(t->lchild==NULL&&t->rchild==NULL){return 1;}else return 0;}else{return f(t->lchild,i+1,k)+f(t->rchild,i+1,k);}
}
int main()   //主函数
{BiTNode *t;CreateBiTree(t);int k;scanf("%d",&k);printf("%d\n",f(t,1,k));
}//main

17121 求二叉树各种节点数
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC

Description
构造二叉链表表示的二叉树:按先序次序输入二叉树中结点的值(一个字符),’#'字符表示空树,构造二叉链表表示的二叉树T,并求此二叉树中度为2的节点总数,度为1的节点总数,度为0的节点总数

#include “stdio.h”
#include “malloc.h”
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;

typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;

Status CreateBiTree(BiTree &T) { // 算法6.4
// 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
// 构造二叉链表表示的二叉树T。
char ch;
scanf("%c",&ch);
if (ch==’#’) T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
________________________ // 生成根结点
_______________________ // 构造左子树
_________________________ // 构造右子树
}
return OK;
} // CreateBiTree

int main() //主函数
{
//补充代码
}//main

输入格式
第一行输入先序次序二叉树中结点
输出格式
第一行输出度为2的节点数
第二行输出度为1的节点数
第三行输出度为0的节点数
输入样例
ABC###D##
输出样例
1
1
2

题解:模拟题

#include "stdio.h"
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK  1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int  Status;typedef char  ElemType;
typedef struct BiTNode{ElemType data;struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;Status CreateBiTree(BiTree &T) {  // 算法6.4// 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,// 构造二叉链表表示的二叉树T。char ch;scanf("%c",&ch);if (ch=='#') T = NULL;else {if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;T->data=ch; // 生成根结点CreateBiTree(T->lchild); // 构造左子树CreateBiTree(T->rchild);  // 构造右子树}return OK;
} // CreateBiTree
int zero,one,two;
void f(BiTree t)
{if(t->lchild!=NULL&&t->rchild!=NULL){two++;f(t->lchild);f(t->rchild);}else if(t->lchild!=NULL&&t->rchild==NULL){one++;f(t->lchild);}else if(t->lchild==NULL&&t->rchild!=NULL){one++;f(t->rchild);}else zero++;return;
}
int main()   //主函数
{BiTree t;CreateBiTree(t);                 //补充代码f(t);printf("%d\n%d\n%d\n",two,one,zero);
}//main

18723 FBI树
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。一个长度为2^n的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
1)T的根结点为R,其类型与串S的类型相同;
2)若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2的n次幂的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历*2序列。

输入格式
第一行是一个整数N(0 ≤ N ≤ 10),第二行是一个长度为2^N的“01”串。
输出格式
一行,这一行只包含一个字符串,即FBI树的后序遍历序列。
输入样例
3
10001011
输出样例
IBFBBBFIBFIIIFF
提示
两种方法:
(1)二叉树首选算法,二分递归。即建树的同时后序遍历
(2)利用完全二叉树性质存储和构造二叉树,再后序遍历。

题解:因为题目是2的几次方,很容易让我们想起线段树,所以直接用数组做个线段树来写感觉会更快一点,当然也可以用指针做二叉树

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int data[10010];
int num;
void p(int x)
{if(data[x]==0){printf("B");}else if(data[x]==1){printf("I");}else printf("F");return;
}
void f(int x)
{if(x>=2*num){return;}f(x*2);f(x*2+1);p(x);return;
}
int main ()
{int n;cin>>n;string s;cin>>s;num=1;for(int i=1;i<=n;i++)num*=2;for(int i=num;i<2*num;i++){if(s[i-num]=='0'){data[i]=0;}else data[i]=1;}int tp=num;while(tp!=1){for(int i=tp;i<2*tp;i+=2){if(data[i]==2||data[i+1]==2){data[i/2]=2;}else if(data[i]==1&&data[i+1]==1){data[i/2]=1;}else if(data[i]==0&&data[i+1]==0){data[i/2]=0;}else data[i/2]=2;}tp=tp/2;}f(1);return 0;
}

18726 查找最接近的元素
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
已知长度为n的非下降序列。
现在有q个查询,每个查询给出一个指定值。
输出序列中第一个大于等于给定值的元素下标,若不存在这样的元素,输出n+1。

输入格式
第一行一个整数n,为非降序列长度。1=<n<=100000。
第二行n个整数,为非降序列元素。所有元素的大小均在int范围内。
第三行包含一个整数q,为要询问的给定值个数。1=<q<=100000。
接下来q行,每行一个整数,为要询问最接近元素的给定值。所有给定值的大小均在int范围内。
输出格式
q行,每行一个整数,第一个大于等于给定值的元素下标,若不存在这样的元素,输出n+1。
输入样例
4
1 3 5 7
2
4
10
输出样例
3
5
提示
样例说明,大于等于4第3个元素,大于等于10不存在,所以输出5

题解:二分来就可以了

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int num[100010];
int f(int l,int r,int x)
{if(l+1==r){if(num[l]>=x){return l;}else return r;}int mid=(l+r)/2;if(x>num[mid]){return f(mid,r,x);}else{return f(l,mid,x);}
}
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}int q;scanf("%d",&q);int x;while(q--){scanf("%d",&x);if(x>num[n]){printf("%d\n",n+1);}else{printf("%d\n",f(1,n,x));}}return 0;
}

18725 宇宙迁跃
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
在基地的科学家发明“透镜”之后,宇宙航行变得更加效率。
作为基地元首的的代理人,你需要在K天内乘坐飞船到达首都川陀。
飞船可以花费一天时间,通过迁跃从一个星系到达另一个星系,但绝不能迁跃到星系之间,那样不但会遇到一些自然危险,也可能永远迷失。
我们把基地至川陀间星系的坐标看成是一个线性序列,例如a星系坐标是10,b星系坐标是15,那么飞船必须具备不小于5的迁跃能力才能从a航行至b。
基地坐标为0,请你根据基地至川陀间的N个星系坐标,计算飞船的迁跃能力至少为多大,才能在K天内(包含K天)到达川陀。

输入格式
第一行两个整数N和K。(1=<N<=10000,1=<K<=10000)
第二行N个整数,表示N个星系的坐标ai,题目确保坐标由小到大排列。(0=<ai<=100000)

输出格式
仅一行,飞船的最小迁跃能力。
输入样例
5 2
1 4 6 10 19
输出样例
10
提示
样例说明:川陀的坐标为最后一个值19。
飞船的迁跃能力至少为10,才能在2天内到达川陀。

题解:我们可以枚举跃迁能力,然后判断可不可以然后找到答案对吧,那怎么枚举呢,二分枚举肯定快,对吧?

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
int num[10010];
int n;
int day;
int g(int x)
{int len=0;int j=0,i=0;for(int k=1;k<=day;k++){int tp=len+x;//这一天能走的最长距离if(tp>=num[n]){return 1;}if(num[j+1]>tp){return 0;}i=j+1;while(num[i]<=tp){i++;}i--;len=num[i];j=i;//printf("*%d\n",j);}if(len>=num[n]){return 1;}else return 0;
}
void f(int l,int r)
{//printf("%d %d\n",l,r);if(l+1==r){if(g(l)){printf("%d\n",l);}else printf("%d\n",r);return;}int mid=(l+r)/2;if(g(mid)){f(l,mid);}else{f(mid,r);}return;
}
int main ()
{scanf("%d%d",&n,&day);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}if(n==1){printf("%d\n",num[1]);return 0;}f(num[1],num[n]);return 0;
}

18727 数对问题一
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
一个长度为N的正整数序列,现在需要计算出有多少对数字的差的绝对值为C。
注意只要位置不同就认为是不相同的数对。

输入格式
第一行,两个整数 N, C。(1=<N<=10000),(1=<C<=10000)
第二行,N个正整数a1…an。 (1=<ai<=10000)
输出格式
仅一行,满足条件的数对的个数。
输入样例
4 1
1 2 3 1
输出样例
3
提示
(a1,a2),(a2,a3),(a2,a4)共3个数对满足条件。

题解:直接对该数值出现多少次进行记录就可以了,范围很小,可以开数组来记录

#include<iostream>
#include<cstdio>
using namespace std;
int num[10010];
int main ()
{int n,c,x;scanf("%d%d",&n,&c);for(int i=1;i<=n;i++){scanf("%d",&x);num[x]++;}int ct=0;for(int i=1;i<=n;i++){if(i+c<=10000){ct+=num[i]*num[i+c];}}printf("%d\n",ct);return 0;
}

18728 数对问题二
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
此题目与数对问题一的唯一区别为序列中元素的取值范围。
一个长度为N的正整数序列,现在需要计算出有多少对数字的差的绝对值为C。
注意只要位置不同就认为是不相同的数对。

输入格式
第一行,两个整数 N, C。(1=<N<=10000),(1=<C<=10000)
第二行,N个正整数a1…an。 ai为int范围内的正整数。
输出格式
仅一行,满足条件的数对的个数。
输入样例
4 1
1 2 3 1
输出样例
3
提示
(a1,a2),(a2,a3),(a2,a4)共3个数对满足条件。

题解:范围变大了,没关系,还是同样的思路,map可以进行关键字记录,所以还是一样的套路。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int num[10010];
map<int,int> m;
int main ()
{int n,c;scanf("%d%d",&n,&c);for(int i=1;i<=n;i++){scanf("%d",&num[i]);m[num[i]]++;}sort(num+1,num+n+1);int cnt=0;for(int i=1;i<=n;i++){if(num[i]==num[i-1]){continue;}cnt+=m[num[i]]*m[num[i]+c];}printf("%d\n",cnt);return 0;
}

18729 太空航站
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
市政府在基地一和基地二之间修建了n个太空航站,其中基地一为第1个航站,基地二为第n个航站,其他航站在两个基地之间。
我们把相邻航站的距离定义为“空间差”,显然飞船的续航能力必须大于等于这个空间差才能在两个航站间航行。
把所有相邻航站间空间差的最大值定义为“空间极差”,如果一艘飞船想从基地一航行至基地二,
那么它的续航能力必须大于等于“空间极差”,这样看能满足航行条件的飞船太少了。
现在市政府打算在基地一和基地二之间新增最多K个太空航站,让尽可能多的飞船可以在基地一和基地二之间航行。
简单说就是让所有航站间的“空间极差”尽可能地小。

输入格式
第一行为两个整数n和k。(2=<n<=100000),(1=<k<=100)
第二行,n个正整数a1…an。(a1<=a2<=a3…<=an)
输出格式
仅一行,新增最多K个太空航站后,“空间极差”的最小值。
输入样例
2 1
0 105
输出样例
53
提示
新的空间站建设在坐标52或53可以得到最小空间极差。

题解:同样我们枚举出极差然后判断极差能不能行就可以了,那怎么枚举,二分鸭!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
int num[100100];
int n,k;
int g(int x)
{int cst=k;for(int i=1;i<n;i++){if(num[i+1]-num[i]<=1){continue;}int pos=0;if((num[i+1]-num[i])%x!=0){pos=1;}cst-=(num[i+1]-num[i])/x+pos-1;}if(cst<0) return 0;else return 1;
}
void f(int l,int r)
{// printf("%d %d\n",l,r);if(l+1==r){if(g(l)){printf("%d\n",l);}else printf("%d\n",r);return ;}if(l==r){printf("1\n");return;}int mid=(l+r)/2;if(g(mid)){f(l,mid);}else f(mid,r);return;
}
int main ()
{scanf("%d%d",&n,&k);int d=0;for(int i=1;i<=n;i++){scanf("%d",&num[i]);d=max(num[i]-num[i-1],d);}int pos=0;for(int i=1;i<n;i++){if(num[i]==num[i+1]){pos=1;}else{pos=0;break;}}if(pos){printf("0\n");return 0;}f(1,d);return 0;
}

18730 涂色问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0

题型: 编程题 语言: 不限定
Description
在某大学的农场里,n间牛舍住着n头奶牛。现在你需要为n间牛舍的外墙涂色,有m种可选颜色。
我们已经知道当相邻两间牛舍颜色相同时,奶牛们会集体发疯。
请问有多少种涂色方案会让奶牛们发疯,由于答案可能较大,输出对1000000007求余的结果。

输入格式
仅一行,两个整数n和m,代表牛舍数量和颜色数量。(1<=n<=1e12),(1<=m<=1e12)

输出格式
仅一样,一个整数代表答案。

输入样例
3 2

输出样例
6

提示
3牛舍2颜色方案有(1,1,1),(1,1,2),(1,2,2),(2,1,1),(2,2,1),(2,2,2),共6种方案会让奶牛发疯。
题解:算出总方案-奶茶不发疯方案,不发疯方案明显就是第一个有m颜色选,第二个m-1,后面都是m-1,然后快速幂求答案就行,最后注意一下减法取模要先加mod。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
#define mod 1000000007
long long pow(long long x,long long i)
{if(i==1){return x%mod;}long long tp=pow(x,i/2);if(i%2==0){return tp*tp%mod;}else return (((tp*tp)%mod)*x)%mod;
}
int main ()
{long long n,m,ans=0;cin>>n>>m;ans=(pow(m,n-1)-pow(m-1,n-1)+mod)%mod;ans=((m%mod)*ans)%mod;cout<<ans<<endl;return 0;
}

18746 逆序数
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。
一个排列中逆序的总数就称为这个排列的逆序数。逆序数是课程线性代数的一个知识点。
现在给定一个排列a1,a2,…,an,如果存在i<j并且ai>aj,那么我们称ai和aj为一个逆序,请求出排列的逆序数。

输入格式
第一行为n,表示排列长度。(1=<n<=100000)
第二行有n个整数,依次为排列中的a1,a2,…,an。所有整数均在int范围内。
输出格式
一个整数代表排列的逆序数。
输入样例
4
3 2 3 2
输出样例
3
提示
注意答案的数据范围。

题解:我们先离散化处理一下数据,在用树状数组或者线段树求和(这是一个模板)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
#define mod 1000000007
int tree[100010];
struct node
{int y;//原始值大小int w;//离散化后大小int p;//数组下标
}data[100010];
int cy[100010];
int n;
int getbit(int x)
{return x&(-x);
}
void updata(int x,int num)
{for(int i=num;i<=n;i+=getbit(i)){tree[i]+=x;}return;
}
int getsum(int x)
{int num=0;for(int i=x;i>0;i-=getbit(i)){num+=tree[i];}return num;
}
bool cmp(struct node a,struct node b)
{return a.y<b.y;
}
int main ()
{scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&data[i].y);data[i].p=i;}sort(data+1,data+1+n,cmp);int j=0;for(int i=1;i<=n;i++){if(i!=1&&data[i].y==data[i-1].y){data[i].w=j;}else{j++;data[i].w=j;}cy[data[i].p]=data[i].w;}long long cnt=0;for(int i=1;i<=n;i++){cnt+=getsum(n)-getsum(cy[i]);updata(1,cy[i]);// printf("%d\n",cnt);}printf("%lld\n",cnt);return 0;
}

18731 最接近的值
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
查找特定的值是一种常见的操作,当数据量较大时,往往需要使用高效的结构和查找算法。
n个整数组成的序列,请输出所有元素左侧与它值最为接近的值,我们定义“最接近”为两数之差的绝对值最小。
例如序列 5 1 4 2,1最接近值为5,4最接近值为5,2最接近值为1。
特别的,第一个数的最接近值为它自身。
如果一个数左侧有两个不同的值,绝对值差都是最小。例如3的左边出现了1和5,我们认为值较大的5为最接近值

输入格式
第一行一个整数n。(1<=n<=100000)
第二行n个整数,均为int范围。
输出格式
一行,n个整数,为输入序列对应元素的最接近值。
输入样例
4
5 1 4 2
输出样例
5 5 5 1

题解:这题一开始有点懵,后来做完后面的题,发现用set就可以解决了,set放已经排序好的数,再去里面二分查找出答案。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
using namespace std;
int num[100010];
int main ()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&num[i]);}printf("%d ",num[1]);set<int> s;s.insert(num[1]);set<int>::iterator it;set<int>::iterator tp;for(int i=2;i<=n;i++){it=s.lower_bound(num[i]);if(it==s.begin()){cout<<*it<<' ';}else if(it==s.end()){tp=--it;cout<<*(tp)<<' ';}else{tp=--it;it++;if(*it-num[i]>num[i]-*(tp)){cout<<*(tp)<<' ';}else cout<<*it<<' ';}s.insert(num[i]);}cout<<endl;
}

18448 最小生成树
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC

Description
给定结点数为n,边数为m的带权无向连通图G,所有结点编号为1,2,3…n。
求图G的最小生成树的边权和。

输入格式
第一行两个正整数n和m。n,m<=2000
之后的m行,每行三个正整数a,b,w,描述一条连接结点a和b,边权为w的边。1=<a,b<=n,w<=10^18。
注意可能存在重边和自环。
输出格式
一个整数表示图G的最小生成树的边权和(注意用长整型)。
输入样例
7 12
1 2 9
1 5 2
1 6 3
2 3 5
2 6 7
3 4 6
3 7 3
4 5 6
4 7 2
5 6 3
5 7 6
6 7 1
输出样例
16

题解:最小生成树模板

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#define mod 1000000007
typedef long long ll;
using namespace std;
ll mmap[2010][2010];
struct node
{ll x,y,w;
}endge[2010];
bool cmp(struct node a,struct node b)
{return a.w<b.w;
}
int f[2010];
int fp(int x)
{if(x!=f[x]){return fp(f[x]);}else return x;
}
int main ()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){cin>>endge[i].x>>endge[i].y>>endge[i].w;mmap[endge[i].x][endge[i].y]=endge[i].w;}for(int i=1;i<=n;i++){f[i]=i;}sort(endge+1,endge+1+m,cmp);ll sum=0;int j=1;for(int i=1;i<n;i++){while(fp(endge[j].x)==fp(endge[j].y)){j++;}sum+=endge[j].w;f[fp(endge[j].x)]=f[fp(endge[j].y)];//cout<<endge[j].x<<' '<<endge[j].y<<endl;;j++;}cout<<sum<<endl;return 0;
}

18732 最短路问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
现在有n个车站和m条直达公交线路,每条线路都有一个固定票价。
作为一个窮人,你打算从车站1坐车到车站n,请计算下车站1到车站n的最少花费。
如果车站1无法到达车站n,请输出-1。
注意,在车站x和y之间可能存在不止一条线路。

输入格式
第一行两个整数n和m,表示车站数量和线路数量。(1<=n<=100),(1<=m<=1000)
第二行至第m+1行,每行3个整数a,b,x,代表车站a和车站b之间有一条票价为x的公交线路,公交线路是双向的。
输出格式
输出车站1到n的最小花费。
输入样例
4 4
1 2 4
2 3 7
2 4 1
3 4 6
输出样例
5

题解:dij跑最短路,模板题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#define mod 1000000007
#define mmax 1000000000007
typedef long long ll;
using namespace std;
ll mmap[2010][2010];
struct node
{ll x,y,w;
}endge[2010];
ll dis[2010];
int tags[2010];
int main ()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){mmap[i][j]=mmax;}}for(int i=1;i<=m;i++){cin>>endge[i].x>>endge[i].y>>endge[i].w;mmap[endge[i].x][endge[i].y]=min(mmap[endge[i].x][endge[i].y],endge[i].w);mmap[endge[i].y][endge[i].x]=min(mmap[endge[i].y][endge[i].x],endge[i].w);}for(int i=1;i<=n;i++){dis[i]=mmap[1][i];}dis[1]=0;tags[1]=1;while(1){ll mmin=mmax,pos=0,p;for(int i=1;i<=n;i++){if(dis[i]!=mmax&&!tags[i]){pos=1;if(mmin>dis[i]){p=i;mmin=dis[i];}}}//cout<<mmin<<endl;tags[p]=1;if(!pos){break;}for(int i=1;i<=n;i++){//cout<<mmap[p][i]<<' '<<dis[i]<<' '<<dis[p]<<' '<<mmap[p][i]<<'*'<<endl;if(mmap[p][i]!=mmax&&dis[i]>dis[p]+mmap[p][i]){dis[i]=dis[p]+mmap[p][i];}}}if(dis[n]==mmax){printf("-1\n");}else cout<<dis[n]<<endl;
}

18733 排队
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
操场上有好多好多同学在玩耍,体育老师冲了过来,要求他们排队。同学们纪律实在太散漫了,老师不得不来手动整队:
“A,你站在B的后面。”
“C,你站在D的后面。”
“B,你站在D的后面。哦,去D队伍的最后面。”

更形式化地,初始时刻,操场上有 n 位同学,自成一列。每次操作,老师的指令是 “x y”,表示 x 所在的队列排到 y 所在的队列的后面,
即 x 的队首排在 y 的队尾的后面。(如果 x 与 y 已经在同一队列,请忽略该指令) 最终的队列数量远远小于 n,老师很满意。
请你输出最终时刻每位同学所在队列的队首(排头),老师想记录每位同学的排头,方便找人。

输入格式
第一行两个整数 n 和 m (n,m≤30000),紧跟着 m 行每行两个整数
x 和 y (1≤x,y≤n)。
输出格式
仅一行 n 个整数,表示每位同学所在队列排头同学的编号。
输入样例
5 4
1 2
2 3
4 5
1 3
输出样例
3 3 3 5 5

题解:并查集模板

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
using namespace std;
#define mod 1000000007
int f[100010];
int fp(int x)
{if(f[x]!=x){return fp(f[x]);}else return x;
}
int main ()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){f[i]=i;}int x,y;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);f[fp(x)]=f[fp(y)];}for(int i=1;i<=n;i++){printf("%d ",fp(i));}printf("\n");return 0;
}

18734 学习
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description

在经历…之后,你打算好好学习下计算机专业的课程,避免面试过程中的各种尴尬场面。
计算机的专业课程间既有循序渐进的特点,相互间也存在着依赖关系(似乎其他专业也是这样…)。
现在给你n门课程和m个课程间关系,请给出一个有效的学习次序。
注意可能存在多门课程不依赖任何其他课程

输入格式
第一行有2个数,分别为课程数n和关系数m。 (1=<n<=20) (1=<m<=30)
接下来有m行,每一行有2个整数a和b,表示课程b依赖于课程a。(1=<a,b<=n)
输出格式
仅一行,一个整数序列,代表课程学习次序。
为确保输出唯一性,同等条件下,编号小的在排在前面。
输入样例
6 8
1 2
1 3
1 4
3 2
3 5
4 5
6 4
6 5
输出样例
1 3 2 6 4 5
提示
图片来源于今日头条。

题解:拓扑排序

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
using namespace std;
#define mod 1000000007
int n,m;
int d[100];//记录出边
int mmap[100][100];
int tags[100];
stack<int> ans;
int main ()
{int n,m,x,y;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);mmap[x][y]=1;d[x]++;}for(int k=1;k<=n;k++){for(int i=n;i>=1;i--){if(!d[i]&&!tags[i]){for(int j=1;j<=n;j++){if(mmap[j][i]==1){d[j]--;}}tags[i]=1;ans.push(i);break;}}}while(!ans.empty()){cout<<ans.top()<<' ';ans.pop();}cout<<endl;return 0;
}

18747 最长路径
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: 不限定

Description
在一个工程项目里,多项工作可以同时进行。
我们可以用有向无环图表述项目流程,把项目中的事件表述为结点,把活动表述成有权值的边。
现在我们已知项目共有n个事件,起点为1,终点为n,m个活动。
请你计算出这个项目的最早完成事件,也就是起点到收点的最长路径。

输入格式
第一行两个整数n和m,代表结点数量和边数量。(1<=n,m<=100)
下面m行,每行3个整数a,b,x,表示点a到点b之间有一条长度为x的有向边。
输出格式
一个整数,起点到终点的最长路径.
输入样例
4 6
1 2 3
1 3 2
1 4 3
2 3 3
2 4 5
3 4 3
输出样例
9

题解:边取负值,跑floyd算法就可以了


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<queue>
#define mod 1000000007
#define mmax 1000000000007
typedef long long ll;
using namespace std;
ll mmap[2010][2010];
struct node
{ll x,y,w;
}endge[2010];
int main ()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){mmap[i][j]=mmax;}}for(int i=1;i<=m;i++){cin>>endge[i].x>>endge[i].y>>endge[i].w;mmap[endge[i].x][endge[i].y]=min(mmap[endge[i].x][endge[i].y],-endge[i].w);}for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){for(int k=1;k<=n;k++){if(mmap[j][i]!=mmax&&mmap[i][k]!=mmax&&mmap[j][k]>mmap[j][i]+mmap[i][k]){mmap[j][k]=mmap[j][i]+mmap[i][k];}}}}cout<<-mmap[1][n]<<endl;
}

撒花!

scau数据结构习题相关推荐

  1. 数据结构c语言函数大全,数据结构习题库(c语言版).doc

    数据结构习题库(c语言版) 第一章 绪 论 一.基本内容 数据.数据元素.数据对象.数据结构.存储结构和数据类型等概念术语的确定含义.抽象数据类型的定义.表示和实现方法.描述算法的类C语言.算法设计的 ...

  2. c语言用两个栈构造队列伪码,数据结构习题线性表栈队列.doc

    数据结构习题线性表栈队列 线性表(58) 1. 在单链表.双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度各为多少? 2.设线性表的 ...

  3. 数据结构习题精解 C语言实现+微课视频(习题解答、研考试题、微课视频)

    数据结构习题精解 C语言实现+微课视频(习题解答.研考试题.微课视频) 配套 数据结构.数据结构C语言实现等经典教材的课后习题解答,著名高校典型考研试题详解.微课视频

  4. c语言 已知某系统在通信联络中,数据结构(习题)..doc

    数据结构(习题). 题1.1 数据结构在计算机内存中的表示是指---. A.数据的存储结构 B.数据元素 C.数据的逻辑结构 D.数据元素之间的关系 题1.2 从逻辑上可把数据结构分为--. A.动态 ...

  5. 数据结构c语言版题库编程,数据结构习题库(c语言版)

    <数据结构习题库(c语言版)>由会员分享,可在线阅读,更多相关<数据结构习题库(c语言版)(104页珍藏版)>请在人人文库网上搜索. 1.wages in arrears. 2 ...

  6. 连通集(浙大数据结构习题)

    连通集(浙大数据结构习题) #include<stdio.h> #include <stdlib.h> #define maxsize 10 #define false 0 # ...

  7. 广工 AnyviewC 数据结构习题 第四章

    广工 AnyviewC 数据结构习题 第四章 广工 AnyviewC 数据结构习题 第四章 1[题目]已知某哈希表的装载因子小于1,哈希函数H(key) 2[题目]假设哈希表长为m,哈希函数为H(x) ...

  8. 数据结构 习题 综合复习

    最近在复习数据结构,所以把做的习题做个总结加小知识点,如果大家有遇到这方面的问题就可以参考一下了,废话不多说,直接开始吧. 1.从一个长度为n的顺序表中删除第i个元素(1<= i <= n ...

  9. 广工 AnyviewC 数据结构习题 第五章

    广工 AnyviewC 数据结构习题 第五章 广工 AnyviewC 数据结构习题 第五章 1[题目]试编写如下定义的递归函数的递归算法: 2[题目]试写出求递归函数F(n)的递归算法: 3[题目]求 ...

最新文章

  1. 学习Python不错的网站
  2. PHP函数stream_context_create()模拟POST/GET
  3. mysql 视图 临时表模式
  4. 红旗Linux软件开发技术,中科红旗闷声研发下一代红旗Linux 11操作系统
  5. USACO3.1.1最短网络
  6. 前段之BOM ----DOM
  7. APP社交类源代码分享直接上车
  8. 国二python考试时间_计算机国二报名每年在几月份
  9. google服务框架 闪退_刷入对应谷歌服务框架之后依然闪退怎么办 解决方方攻略...
  10. java sql编写教务系统_教务管理系统的设计与实现(SQLServer)
  11. 传感器自学笔记第三章——LM393电压比较芯片+MQ_2烟雾传感器
  12. QQ红包金额分配算法
  13. android卡在开机画面,请教:用迅为4412开发板开机时卡在Android静止画面
  14. docker的容器间通信
  15. Barsetto百胜图美式便携咖啡机测评只为一杯好咖啡
  16. 用光盘怎样重装电脑系统
  17. 取球游戏(C++)[堆]
  18. 电子计算机二级的模拟试题,计算机二级模拟试题
  19. mysql error unpacking_error: unpacking of archive failed on file错误的解决
  20. 联合索引,组合索引,详细应用实例

热门文章

  1. STM32F系列ARM Cortex-M3核微控制器基础之系统时钟一
  2. ZigBee基础知识(二)
  3. 【翻译】如果软件工程需求旺盛,但为什么找一份软件工程工作这么难?
  4. 用Powerpoint打开ppt文件出现提示:PowerPoint无法显示文件中某些幻灯片中的文字、图像或对象,“xx.ppt”解决办法
  5. (4)绪论三:归纳偏好
  6. 小米一键解锁system分区_小米note3开启全面屏手势、禁用经典物理按键教程
  7. 关于使用C++万能头文件时定义y1报编译错误的那点事
  8. 序列召回基础+GRU4Rec论文阅读
  9. Windows Server 2012 R2下补丁服务器部署与配置
  10. 第6课:郭盛华课程_VB编程之TextBox控件的使用方法