PAT刷题笔记

1001:Public Bike Management

题目大意:自行车数量管理,有一问题站点,解决问题求路径最短,并且让图中每一个站点的自行车数量都为c/2,outbikes最小,inbikes最小;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;

/**************************
* Public Bike Management
总体思路:
深搜可以求出两点间的所有可达路径
只要在找到可行路径时判断当前路径是否是更优路径即可。注意回溯*
**************************/

int c,n,s,m;//最大承载bike量<=100
//站点数<=500
//问题站点
//路径数
vector<vector<int> > edge;//存放路径(注意空格)
vector<bool>vis;//访问标记
vector<int>bikes;//各站点bike数量
vector<int>path,res_path;
int cost=2,res_inbikes,res_outbikes,res_len=0;
int res_cost=99999999;
//使用vector防止内存溢出

void DFS(int e,int index)
{
//到达终点,判断该路径是否最优
if(index==e){
//计算in/outbikes
int in=0,out=0;
/* for(int i=0;i<path.size();i++){
cout<<path[i]<<" ";
}*/
for(int i=0;i<path.size();i++){
if(bikes[path[i]]>=c/2){
in+=bikes[path[i]]-c/2;
}
else {
if((c/2-bikes[path[i]])<=in){//bug1
in-=(c/2-bikes[path[i]]);
}
else {
out+=(c/2-bikes[path[i]])-in;
// cout<<in<<" "<<out<<endl;
in=0;
}
}

}
//比较
if(cost!=res_cost){
if(cost<res_cost){
res_cost=cost;
res_inbikes=in;
res_outbikes=out;
res_path=path;
}
}
else {
if(out!=res_outbikes){
if(out<res_outbikes){
res_cost=cost;
res_inbikes=in;
res_outbikes=out;
res_path=path;
}
}
else{
if(in<res_inbikes){
res_cost=cost;
res_inbikes=in;
res_outbikes=out;
res_path=path;
}
}
}
}
else {
for(int i=1;i<=n;i++){
if(edge[index][i]!=0&&!vis[i]){
vis[i]=1;
cost+=edge[index][i];
path.push_back(i);
DFS(e,i);
vis[i]=0;
cost-=edge[index][i];
path.pop_back();
}
}
}
}

int main()
{
cin>>c>>n>>s>>m;
bikes.resize(n+1,0);
vis.resize(n+1,0);
edge.resize(n+1,vector<int>(n+1,0));
int si,sj,t;
for(int i=1;i<=n;i++){
cin>>bikes[i];
}
for(int i=0;i<m;i++){
cin>>si>>sj>>t;
edge[si][sj]=t;
edge[sj][si]=t;
}
vis[0]=1;
DFS(s,0);
cout<<res_outbikes<<" 0";
for(int i=0;i<res_path.size();i++){
cout<<"->"<<res_path[i];
}
cout<<" "<<res_inbikes<<endl;
return 0;
}

1002:All Roads Lead to Rome

和前面一题一样的思路,图的DFS确定所有可以到目的地的路线,按照一定规则选取最优路径,并存储;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <iostream>
#include <string.h>
#include <map>
#include <vector>

using namespace std;

int n,k;//城市数,路径数
string start_city;

map<string,int> mapcity;//记录城市信息
map<int,string> mapcity2;
vector<vector<int> > roads;//记录路径
vector<int> happiness;//记录幸福
vector<bool> vis;
vector<int>path,res_path;
int cost=0,res_cost=999999999,res_hsum=0,res_havg=0,roadnum=0;
int nowh_sum=0,nowh_avg=0;

void DFS(int index,int e)
{
//走到罗马了
if(index==e){
nowh_avg=nowh_sum/(path.size()-1);
//判断cost与幸福总值与均值
if(cost!=res_cost){
if(cost<res_cost){
res_path=path;
res_cost=cost;
res_hsum=nowh_sum;
res_havg=nowh_avg;
roadnum=1;
}
}
else {
roadnum++;
if(nowh_sum!=res_hsum){
if(nowh_sum>res_hsum){
res_path=path;
res_cost=cost;
res_hsum=nowh_sum;
res_havg=nowh_avg;
}
}
else {
if(nowh_avg>res_havg){
res_path=path;
res_cost=cost;
res_hsum=nowh_sum;
res_havg=nowh_avg;
}
}
}
}
else {
for(int i=1;i<n;i++){
if(roads[index][i]!=0&&!vis[i]){
vis[i]=1;
path.push_back(i);
cost+=roads[index][i];
nowh_sum+=happiness[i];
DFS(i,e);
vis[i]=0;
path.pop_back();
cost-=roads[index][i];
nowh_sum-=happiness[i];
}
}
}
}

int main()
{
cin>>n>>k>>start_city;
string cityname;
int h,end_index=0;

vis.resize(n,0);
roads.resize(n,vector<int>(n,0));
happiness.resize(n,0);

mapcity[start_city]=0;
mapcity2[0]=start_city;
for(int i=1;i<n;i++){
cin>>cityname>>h;
if(cityname=="ROM")end_index=i;
mapcity[cityname]=i;
happiness[i]=h;
mapcity2[i]=cityname;
}

string city1,city2;
int cost;
for(int i=0;i<k;i++){
cin>>city1>>city2>>cost;
int x=mapcity[city1];
int y=mapcity[city2];
roads[x][y]=cost;
roads[y][x]=cost;
}
vis[0]=1;
path.push_back(0);
DFS(0,end_index);
cout<<roadnum<<" "<<res_cost<<" "<<res_hsum<<" "<<res_havg<<endl;
for(int i=0;i < res_path.size();i++){
if(i!=0)cout<<"->";
cout<<mapcity2[res_path[i]];
}
return 0;
}

1003:Highest Price in Supply Chain

刚开始没有理解题意,题意是分别输入以0-N-1为下标的父母结点的下标;
解题思路:按照输入建树,求层数;
使用一个向量数组存放当前结点的子节点:vector tree[100010];用树的DFS求层数;
注意树的DFS不需要vis标记访问,因为从根节点到达某一结点有且只有一条路径;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

vector<int> tree[100010];
int N;
double P,r;
int root;//记录根节点位置
int routes=0,maxdepth=0;

void dfs(int index,int step)
{
if(tree[index].size()==0){//到达树的子结点
if(step>maxdepth){
maxdepth=step;
routes=1;
}
else if(step==maxdepth)routes++;
}
for(int i=0;i<tree[index].size();i++){
dfs(tree[index][i],step+1);
}
}

int main()
{
scanf("%d%lf%lf",&N,&P,&r);
r=r/100+1;
int parent;
//输入i的父母结点
for(int i=0;i<N;i++){
cin>>parent;
//将i存为parent的子结点
if(parent==-1){
root=i;
}
else {
tree[parent].push_back(i);
}
}
//dfs确定树的深度
dfs(root,1);
double tmp=1;
for(int i=0;i<maxdepth-1;i++)tmp*=r;
printf("%.2lf %d",tmp*P,routes);
return 0;
}

1004:Acute Stroke

三维的BFS,用DFS时间复杂度过大;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <queue>
using namespace std;

int M,N,L,T;//矩阵的高<1286
//矩阵的宽<128
//slice数<=60
int arr[65][1290][130];
int res=0;
int dir[6][3]=
{
{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,-1},{0,0,1}
};//6个方向:上下前后左右
struct node
{
int x,y,z;
node(int _x, int _y, int _z){
x=_x; y=_y; z=_z;
}
};

void BFS(int i,int j,int k)
{
queue<node> q;
q.push(node(i,j,k));
arr[i][j][k]=0;
int sum=1;
while(!q.empty())
{
node n=q.front();
q.pop();
for(int i=0;i<6;i++){
int x=n.x+dir[i][0];
int y=n.y+dir[i][1];
int z=n.z+dir[i][2];
//cout<<x<<" "<<y<<" "<<z<<" "<<tmp<<endl;
if(x<L&&x>=0&&y<M&&y>=0&&z<N&&z>=0){
if(arr[x][y][z]==1){
q.push(node(x,y,z));
arr[x][y][z]=0;
sum++;
}
}
}
}
//cout<<sum<<endl;
if(sum>=T)res+=sum;
}


int main()
{
cin>>M>>N>>L>>T;
int thickness=0;
for(int i=0;i<L;i++){
for(int j=0;j<M;j++){
for(int k=0;k<N;k++){
cin>>thickness;
arr[i][j][k]=thickness;
}
}
}
for(int i=0;i<L;i++){
for(int j=0;j<M;j++){
for(int k=0;k<N;k++){
//cout<<arr[i][j][k];
if(arr[i][j][k])BFS(i,j,k);
}
}
}
cout<<res<<endl;
return 0;
}

1005:The Largest Generation

家谱树问题,求结点最多的一层的结点数与层数;思路:使用vector数组保存每个结点的孩子,构建成家谱树,然后使用BFS计算每层结点数,过程中维护家谱树每一层的level,使用一个数组记录各层结点数;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>

using namespace std;

struct node
{
vector<int> child;
int level;
}members[101];
int vis[101];//访问标记
int N,M;//总人数,有孩子的人数
int gen=0;
void BFS()
{
queue<node> que;
que.push(members[1]);
vis[1]=1;
while(!que.empty()){
node n=que.front();
que.pop();
for(int i=0;i<n.child.size();i++){
int index=n.child[i];
vis[n.level+1]++;
members[index].level=n.level+1;
que.push(members[index]);
if(gen!=n.level)gen=n.level;
}
}
}

int main()
{
memset(vis,0,sizeof(vis));
cin>>N>>M;
int id,K;
//输入构建家谱树
for(int i=0;i<M;i++)
{
int c;
cin>>id>>K;
for(int j=0;j<K;j++){
cin>>c;
members[id].child.push_back(c);
if(c==1)members[id].level=1;
else members[id].level=0;
}
}
BFS();
int res=0,res_i=0;
for(int i=1;i<gen;i++){
if(vis[i]>res){
res=vis[i];
res_i=i;
}
}
cout<<res<<" "<<res_i+1<<endl;
return 0;
}

1006:Cars on Campus

题目意思是给出一组车进出记录,给定时刻,算出状态还未in的车的数量,并且求出一天中停留时间最长的车牌号与时间;
题目不难,在理解题意上花了一点时间,主要是pat惯用的需要建立一个专用的数据结构node存储记录;
数据量较大,容易超时,刚开始用char type[4]来存储记录的状态,因此每次都需要调用strcmp函数对字符串进行比较,后改为bool字段,直接在输入时判断为in(true)/out(false),没有超时;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <iostream>
#include <cstdio>
#include <string.h>
#include <map>
#include <algorithm>
#include <vector>

using namespace std;
vector<string> ans;
struct node
{
int time;
char name[8];
bool type;
}record[10001],valid[10001];

int timeToInt(int h,int m,int s)
{
return h*3600+m*60+s;
}

bool cmp1(node a,node b)
{
int x=strcmp(a.name,b.name);
if(x)return x<0;
return a.time<b.time;
}

bool cmp2(node a,node b)
{
return a.time<b.time;
}

int main()
{
int n,k;
int hh,mm,ss;
//存储每辆车的停留时间
map<string,int>parkTime;
int maxTime=0;
char t[4];
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++){
scanf("%s %d:%d:%d %s",record[i].name,&hh,&mm,&ss,t);
if(!strcmp(t,"in"))record[i].type=true;
else record[i].type=false;
record[i].time=timeToInt(hh,mm,ss);
}
//按照name与time从小到大排序
sort(record,record+n,cmp1);
int num=0;
//筛选有效记录,并求出最长停留时间
for(int i=0;i<n-1;i++){
// printf("%s %d %s\n",record[i].name,record[i].time,record[i].type);
if(!strcmp(record[i].name,record[i+1].name)&&
record[i].type&&!record[i+1].type){
valid[num++]=record[i];
valid[num++]=record[i+1];
int time=record[i+1].time-record[i].time;
if(parkTime.count(record[i].name)==0){
parkTime[record[i].name]=0;
}
parkTime[record[i].name]+=time;
if(maxTime<parkTime[record[i].name]){
maxTime=parkTime[record[i].name];
ans.clear();
ans.push_back(record[i].name);
}
else if(maxTime==parkTime[record[i].name]){
ans.push_back(record[i].name);
}
}
}
//按照time从小到大排序
sort(valid,valid+num,cmp2);
//输入搜索时间,从记录中选择计算
for(int i=0;i<k;i++){
scanf("%d:%d:%d",&hh,&mm,&ss);
int sum=0;
int temp=timeToInt(hh,mm,ss);
for(int j=0;j<num;j++){

if(valid[j].time>temp)break;
if(valid[j].type)sum++;
else sum--;
}
cout<<sum<<endl;
}
/*map<string,int>::iterator it;
for(it=parkTime.begin();it!=parkTime.end();it++){
if(it->second==maxTime)printf("%s ",it->first.c_str());
}*/
for(int i=0;i<ans.size();i++){
cout<<ans[i]<<" ";
}
printf("%02d:%02d:%02d\n", maxTime / 3600, maxTime % 3600 / 60, maxTime % 60);
return 0;
}

1007:Consecutive Factors

题目大意:求一个数的最长的连续因数串;
思路:从1到sqrt(n)的范围内循环,计算从当前i开始能够被n整除的最长子串,保存比较长度,最后得出最长;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <math.h>
#include <vector>

using namespace std;
vector<int> ans,temp;

int main()
{
int n;
cin>>n;
int tempn=(int)sqrt(n);
//cout<<tempn<<endl;
int x=1,num=0,res=0;
for(int i=2;i<=tempn;i++){
x*=i;
int t=i;
while(n%x==0&&t<=tempn){
temp.push_back(t);
t++;
x*=t;
}
if(temp.size()>ans.size()){
ans=temp;
}
x=1;
temp.clear();
}
if(ans.size()==0){
cout<<1<<endl;
cout<<n;
} else {
cout<<ans.size()<<endl;
for(int i=0;i<ans.size();i++){
cout<<ans[i];
if(i!=ans.size()-1)cout<<"*";
}
}
return 0;
}

1008:Deduplication on a Linked List

题目大意:将链表式数组中绝对值重复的值取出来,放入一个新的数组中,需要输入当前地址,值,以及下一个地址值;
我的思路:

  1. 使用特定数据结构存储add,value,next,初始化按照链表顺序排好序;
  2. 从表头结点开始遍历,判断下一个结点的值是否出现过,flag[10001]表示是否出现过标记;
  3. 出现过则需要改变当前结点的next值,同时把重复结点赋予新数组,改变新数组的前一个结点的next值;
    超时了!主要时间复杂度在排序O(n^2)!
    不超时思路:
  4. 空间换取时间,直接在当前地址存储value/next,inList[add].value=v;inList[add].next=n;
  5. 从起始地址开始,判断当前value是否访问过,removeList[] 与 outList[]存放最终结果各个结点的地址
  6. 遍历输出List[i],inList[List [i]].value,List[i+1];
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #include <iostream>
    #include <algorithm>
    #include <string.h>
    #include <stdio.h>

    using namespace std;
    int num,first;
    /*
    struct node
    {
    int add,value,next;
    bool sign;
    }List[100001],removeList[100001];
    int flag[10001];
    int s_index;
    void InitNode()
    {
    int nnum=1;
    List[0]=removeList[s_index];
    int n=removeList[s_index].next;
    while(n!=-1){
    for(int j=0;j<num;j++){
    if(removeList[j].add==n){
    List[nnum++]=removeList[j];
    n=removeList[j].next;
    break;
    }
    }
    }
    }

    int main()
    {
    int removenum=0;
    cin>>first>>num;
    memset(flag,0,sizeof(flag));
    for(int i=0;i<num;i++){
    cin>>removeList[i].add>>removeList[i].value>>removeList[i].next;
    if(removeList[i].add==first)s_index=i;
    }
    InitNode();
    flag[abs(List[0].value)]=1;
    for(int i=0;i<num-1;i++){
    int v=abs(List[i+1].value);
    //发生重复
    if(flag[v]!=0){
    //从链表中去除结点
    List[i].next=List[i+1].next;
    //加入到remove链表中
    if(removenum==0)removeList[removenum++]=List[i+1];
    else {
    removeList[removenum-1].next=List[i+1].add;
    removeList[removenum++]=List[i+1];
    }
    List[i+1].sign=true;
    }
    else flag[v]=1;
    }
    int t=0,f=0;
    for(int i=0;i<num;i++){
    if(!List[i].sign){
    if(t==num-removenum-1){
    printf("%05d %d %d\n",List[i].add,List[i].value,-1);break;
    }
    printf("%05d %d %05d\n",List[i].add,List[i].value,List[i].next);
    t++;
    }
    }
    for(int i=0;i<removenum;i++){
    if(i==removenum-1)
    printf("%05d %d %d\n",removeList[i].add,removeList[i].value,-1);
    else printf("%05d %d %05d\n",removeList[i].add,removeList[i].value,removeList[i].next);
    }
    return 0;
    }*/
    #define MAX 100001
    struct node
    {
    int value,next;
    }inList[MAX];
    int outList[MAX],removeList[MAX];
    bool flag[10001]={0};
    int s_index=0;

    int main()
    {
    scanf("%d%d",&first,&num);
    int add;
    for(int i=0;i<num;i++){
    cin>>add;
    scanf("%d%d",&inList[add].value,&inList[add].next);
    if(add==first)s_index=add;
    }
    int temp=s_index;
    int p=0,q=0;
    int rfirst=0;
    while(temp!=-1){
    int v=abs(inList[temp].value);
    //发生冲突
    if(flag[v]){
    if(q==0)rfirst=inList[temp].value;
    removeList[q++]=temp;
    }
    else {
    outList[p++]=temp;
    flag[v]=1;
    }
    temp=inList[temp].next;
    }
    //输出
    for(int i=0;i<p;i++){
    if(i!=p-1){
    //printf("%05d %d %05d\n",outList[i].value,outList[i+1].value);
    printf("%05d %d %05d\n",outList[i],inList[outList[i]].value,outList[i+1]);
    }
    else printf("%05d %d %d\n",outList[i],inList[outList[i]].value,-1);
    }
    for(int i=0;i<q;i++){
    if(i!=q-1){
    printf("%05d %d %05d\n",removeList[i],inList[removeList[i]].value,removeList[i+1]);
    }
    else printf("%05d %d %d\n",removeList[i],inList[removeList[i]].value,-1);
    }
    }

    1009:Insertion or Heap Sort

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    #include <iostream>
    #include <math.h>
    using namespace std;

    int num[101];
    int num2[101];
    int res[101];
    int Heap_Size=0;
    bool flag=false;
    bool isSame(int arr[],int len)
    {
    for(int i=0;i<len;i++){
    if(arr[i]!=res[i])return false;
    }
    return true;
    }
    void out_put(int arr[],int len)
    {
    for(int i=0;i<len;i++){
    if(i!=0)cout<<" ";
    cout<<arr[i];
    }
    }
    //插入排序
    bool Insert_Sort(int arr[],int len)
    {
    for(int i=1;i<len;i++){
    int temp=arr[i];
    int j;
    for(j=i-1;j>=0;j--){
    if(arr[j]>temp){
    arr[j+1]=arr[j];
    }
    else {
    break;
    }
    }
    arr[j+1]=temp;
    if(flag){
    out_put(arr,len);
    return true;
    }
    if(isSame(arr,len)){
    cout<<"Insertion Sort"<<endl;
    flag=true;
    }
    }
    return false;
    }

    void Max_Heap(int arr[],int i)
    {
    int l=2*(i+1)-1;
    int r=2*(i+1);
    int largeset=i;
    if(arr[l]>arr[i]&&l<Heap_Size){
    largeset=l;
    }
    if(arr[r]>arr[largeset]&&r<Heap_Size){
    largeset=r;
    }
    if(largeset!=i){
    swap(arr[largeset],arr[i]);
    Max_Heap(arr,largeset);
    }
    }

    //建最大堆
    void Build_Max_Heap(int arr[],int len)
    {
    //从第一个非叶子结点开始
    for(int i=len/2-1;i>=0;i--)
    {
    Max_Heap(arr,i);
    }
    }

    bool Heap_Sort(int arr[],int len)
    {
    Heap_Size=len;
    Build_Max_Heap(arr,len);
    for(int i=0;i<len-1;i++){
    if(flag){
    out_put(arr,len);
    return true;
    }
    if(isSame(arr,len)){
    cout<<"Heap Sort"<<endl;
    flag=true;
    }
    swap(arr[Heap_Size-1],arr[0]);
    Heap_Size--;
    Build_Max_Heap(arr,Heap_Size);
    }
    return false;
    }

    int main()
    {
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
    cin>>num[i];
    num2[i]=num[i];
    }
    for(int i=0;i<n;i++){
    cin>>res[i];
    }
    if(!Insert_Sort(num,n))
    Heap_Sort(num2,n);
    return 0;
    }

    1010:Build A Binary Search Tree

    根据输入构造二叉树,利用二叉搜索树的排序特点,将key[]从小到大排序后,就是BST的中序遍历的顺序,因此可以为BST直接赋值,再用queue层次遍历,实际上就是树的BFS;
    刚开始还想要按照传统方法输入建树,也太蠢了吧!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <iostream>
    #include <algorithm>
    #include <queue>

    using namespace std;
    struct treeNode
    {
    int left;
    int right;
    int value;
    }Tree[101];
    int key[101];
    int index=0;

    //中序遍历
    void mid(int t)
    {
    if(t==-1)return;
    mid(Tree[t].left);
    Tree[t].value=key[index++];
    mid(Tree[t].right);
    }

    //层次遍历
    void BFS()
    {
    bool flag=false;
    queue<treeNode>q;
    q.push(Tree[0]);
    while(!q.empty())
    {
    treeNode n=q.front();
    q.pop();
    if(flag)cout<<" ";
    flag=true;
    cout<<n.value;
    if(n.left!=-1)q.push(Tree[n.left]);
    if(n.right!=-1)q.push(Tree[n.right]);
    }
    }

    int main()
    {
    int num;
    cin>>num;
    for(int i=0;i<num;i++){
    cin>>Tree[i].left>>Tree[i].right;
    }
    for(int i=0;i<num;i++){
    cin>>key[i];
    }
    sort(key,key+num);
    //for(int i=0;i<num;i++)cout<<key[i]<<" ";
    mid(0);
    BFS();
    return 0;
    }

    1011:Forwards on Weibo

    太感动了,思路都是自己想出来的!
    挺切合实际的,
  7. 用vector二维数组保存微博关注者;
  8. 使用queue保存每一level转发者;注意保存的是自己设定的node,其中包括level,保证转发层次在一定范围内;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <iostream>
    #include <vector>
    #include <queue>
    #include <string.h>
    using namespace std;

    vector<vector <int> > User;
    int flag[1001];//标记是否转发过
    int N=0;//user数<=1000
    int level=0;//follow层数<=6
    int qnum=0;//查询次数

    struct node
    {
    int index;
    int Lev;
    node(int _index, int _lev){
    index=_index;
    Lev=_lev;
    }
    };

    int main()
    {
    cin>>N>>level;
    int num;//关注人数
    int follow;//关注人的下标值
    User.resize(N+1);
    //输入,记录关注者
    for(int i=1;i<=N;i++){
    cin>>num;
    for(int j=0;j<num;j++){
    cin>>follow;
    User[follow].push_back(i);
    }
    }
    /* cout<<"------------------------------"<<endl;
    for(int i=1;i<=N;i++){
    for(int j=0;j<User[i].size();j++){
    cout<<User[i][j]<<" ";
    }
    cout<<endl;
    }*/
    cin>>qnum;
    int k;
    int sum=0;
    for(int i=0;i<qnum;i++){
    cin>>k;
    queue<node> q;
    memset(flag,0,sizeof(flag));
    sum=0;
    flag[k]=1;
    q.push(node(k,0));
    while(!q.empty()){
    node temp=q.front();
    q.pop();
    //cout<<temp.index<<" "<<temp.Lev<<endl;
    int now_level=temp.Lev;
    if(now_level>=level)break;
    for(int j=0;j<User[temp.index].size();j++){
    if(!flag[User[temp.index][j]]){
    sum+=1;
    q.push(node(User[temp.index][j],now_level+1));
    flag[User[temp.index][j]]=1;
    }
    }
    }
    cout<<sum<<endl;
    // cout<<"------------------------------"<<endl;
    }
    return 0;
    }

    1012:Kuchiguse

    char str[101][256]字符数组的输入:scanf(“%s”,&str[i]) / string str[101]字符串输入:cin>>str[i],以空格为分割字符串;
    简单题,求N个字符串的最长公共后缀,思路:以第一个字符串为基准,遍历另外N-1个字符串,判断从后往前的同样位置字符是否相等;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <iostream>
    #include <stdio.h>
    #include <string.h>

    using namespace std;
    string str[101];
    int main()
    {
    int num;
    cin>>num;
    getchar();
    for(int i=0;i<num;i++){
    getline(cin,str[i]);
    }
    bool flag=false;
    int res=0;
    for(int i=0;i<str[0].length();i++){
    char temp=str[0][str[0].length()-i-1];
    for(int j=1;j<num;j++){
    char x=str[j][str[j].length()-i-1];
    if(x!=temp){
    res=i;
    flag=true;
    break;
    }
    }
    if(flag)break;
    }
    if(res==0&&flag)//bugcout<<"nai"<<endl;
    else if(res==0){
    for(int i=0;i<str[0].length();i++)cout<<str[0][i];
    }
    else
    for(int i=str[0].length()-res;i<str[0].length();i++)cout<<str[0][i];
    /* for(int i=0;i<num;i++){
    cout<<str[i]<<endl;
    }*/
    return 0;
    }

    1013:Hashing

    Hash+平方探测法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    #include <iostream>
    #include <math.h>
    #include <string.h>

    using namespace std;

    bool isPrime(int x)
    {
    if(x==1)return false;
    if(x==2)return true;
    int temp=sqrt(x);
    for(int i=2;i<=temp;i++){
    if(x%i==0)return false;
    }
    return true;
    }

    //找到比x大的最近一个质数
    int Find_Prime(int x)
    {
    while(1){
    if(isPrime(x))return x;
    x++;
    }
    }

    int main()
    {
    int MSize,N;
    bool flag[10001];
    int input[10001];
    bool ff=false,fff=false;
    memset(flag,0,sizeof(flag));
    cin>>MSize>>N;
    int table_size;
    //if(MSize==1)table_size=2;
    table_size=Find_Prime(MSize);
    int num;
    for(int i=0;i<N;i++){
    cin>>input[i];
    }
    for(int i=0;i<N;i++){
    int num=input[i];
    int a=num%table_size;
    if(ff)cout<<" ";
    if(!flag[a]){
    cout<<a;
    flag[a]=1;
    fff=true;
    }
    //平方探测法
    else {
    for(int x=1;x<table_size;x++){//bug
    int t=(x*x+a)%table_size;
    if(!flag[t]){
    cout<<t;
    fff=true;
    flag[t]=1;
    break;
    }
    }
    }
    if(!fff)cout<<"-";
    ff=true;
    fff=false;
    }
    return 0;
    }

    1014:Total Sales of Supply Chain

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <iostream>
    #include <vector>
    #include <stdio.h>
    #include <math.h>

    using namespace std;

    double sum=0;
    vector<vector<int> > tree;
    int N;//结点总数
    double P,r;//根结点的原始值,rate
    int flag[100001];//标记子节点的产品值

    void DFS(int index,int level)
    {
    //说明为叶子结点
    //可结合产品数量计算金额
    if(tree[index].size()==0){
    //这儿存在bug,一个超时,一个错误
    //改用pow函数即可
    /*double t=r;
    for(int k=0;k<level-1;k++){
    t=r*t;
    }*/
    sum+=pow(r,level)*P*flag[index];
    return;
    }
    for(int i=0;i<tree[index].size();i++){
    DFS(tree[index][i],level+1);
    }
    }

    int main()
    {
    scanf("%d %lf %lf",&N,&P,&r);
    r=(double)1+r/100;
    tree.resize(N);
    int childnum;
    //输入
    for(int i=0;i<N;i++){
    scanf("%d",&childnum);
    if(childnum!=0){
    int child;
    //记录各个结点的子节点
    for(int j=0;j<childnum;j++){
    cin>>child;
    tree[i].push_back(child);
    }
    }
    else {
    int products;
    scanf("%d",&products);
    flag[i]=products;
    }
    }

    //DFS求出遍历所有路径
    DFS(0,0);
    printf("%.1lf",sum);
    return 0;
    }

    1015Graduate Admission

    优先队列,pop(),push(),top(),没法遍历;
  • 自定义优先级
    struct cmp{
    operator bool(int x,int y){return x>y;}
    }
    priority_queue<int,vector,cmp>
  • 结构体声明方式
    struct node{
    int x,y;
    friend bool operator < (node a, node b)
      {
        return a.x > b.x; //结构体中,x小的优先级高
      }
    }
    priority_queueq;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    #include <iostream>
    #include <vector>
    #include <algorithm>

    using namespace std;

    int nums,schools,chs;//毕业人数<=40000,
    //院校数<=100,
    //志愿数<=5
    vector<int>quotas;//院校招生限额

    struct node
    {
    int index;
    int GE;
    int GT;
    vector<int>choices;
    }Students[40001];
    vector<node>SchoolsStu[101];//院校招生学生

    bool cmp(node a,node b)
    {
    //两个double!!!
    double x=(double)(a.GE+a.GT)/2;
    double y=(double)(b.GE+b.GT)/2;
    if(x!=y)return x>y;
    else return a.GE>b.GE;
    }

    bool cmp2(node a,node b)
    {
    return a.index<b.index;
    }

    bool isEqual(node a,node b)
    {
    //两个double!!!
    double x=(double)(a.GE+a.GT)/2;
    double y=(double)(b.GE+b.GT)/2;
    if(x==y&&a.GE==b.GE)return true;
    return false;
    }

    int main()
    {
    //输入
    cin>>nums>>schools>>chs;
    int quo;
    for(int i=0;i<schools;i++){
    cin>>quo;
    quotas.push_back(quo);
    }
    for(int i=0;i<nums;i++){
    Students[i].index=i;
    Students[i].choices.resize(chs);
    cin>>Students[i].GE>>Students[i].GT;
    int temp;
    for(int j=0;j<chs;j++){
    cin>>temp;
    Students[i].choices[j]=temp;
    }
    }

    //计算
    sort(Students,Students+nums,cmp);
    for(int i=0;i<nums;i++){
    for(int j=0;j<chs;j++){
    int tempc=Students[i].choices[j];
    if(quotas[tempc]>SchoolsStu[tempc].size()){
    SchoolsStu[tempc].push_back(Students[i]);
    break;
    }
    else {
    //无需用循环!
    //用循环复杂度极高,实际上只要对比新加入的最菜的那个学生即可
    if(isEqual(SchoolsStu[tempc].back(),Students[i])){
    SchoolsStu[tempc].push_back(Students[i]);
    break;
    }

    }
    }
    }

    //输出
    /*cout<<"============================="<<endl;
    for(int i=0;i<nums;i++){
    cout<<Students[i].GE<<" "<<Students[i].GT<<" ";
    for(int j=0;j<Students[i].choices.size();j++){
    int xx=Students[i].choices[j];
    cout<<xx<<" ";
    }
    cout<<endl;
    }
    cout<<"============================="<<endl;*/
    for(int i=0;i<schools;i++){
    //vector的排序方式
    sort(SchoolsStu[i].begin(),SchoolsStu[i].end(),cmp2);
    for(int j=0;j<SchoolsStu[i].size();j++){
    if(j!=0)cout<<" ";
    cout<<SchoolsStu[i][j].index;
    }
    cout<<endl;
    }
    return 0;
    }

1021

一开始题目看错,用空间换取时间,出现段错误,因为数组越界;
使用了map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <map>

using namespace std;

map<int,int> myMap[55];
int flag[55];

int main()
{
//N集合数<=50
//K每个集合的整数个数<=10^4,在[0,10^9]内
//Q查询数
//想用Set[55][110000000]空间换取时间,根本不ok
//换个思路
int N,K,Q,data;
map<int,int>::iterator it;
cin>>N;
memset(flag,0,sizeof(flag));
for(int i=0;i<N;i++){
cin>>K;
for(int j=0;j<K;j++){
cin>>data;
it=myMap[i].find(data);
if(it==myMap[i].end()){
myMap[i][data]=1;
// flag[i]++;
}
else {
myMap[i][data]++;
}
//可直接myMap[i][data]++;
}
}
cin>>Q;
int set1,set2;
for(int i=0;i<Q;i++){
int NC=0,NT=0;
double ret=0;
cin>>set1>>set2;
map<int,int>::iterator iit;
for(iit=myMap[set1-1].begin();iit!=myMap[set1-1].end();iit++){
int temp=iit->first;
it=myMap[set2-1].find(temp);
if(it!=myMap[set2-1].end()){
//找到了
NC++;
}
}
// cout<<NC<<" "<<flag[set1-1]+flag[set2-1]-NC<<endl;
ret=(double)NC*100/(myMap[set1-1].size()+myMap[set2-1].size()-NC);
printf("%.1lf%%\n",ret);
}
return 0;
}