您的位置:首页 > 其它

CCCC L2-025 L2-026 L2-027

2018-04-03 21:38 260 查看
赛场上第一题内存超限,第二题超时,其实只要稍微一转换就能过,没想到啊,可能与平时做题有关系

1、L2-025 分而治之

内存超限是因为我用邻接矩阵存的,不应该,邻接表只学过数组怎么实现,其实vector更直观,也易实现

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
#define N 100005
vector<int>ve
;
bool vis
;
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i = 0;i < m;++i)
{
int x,y;
scanf("%d %d",&x,&y);
ve[x].push_back(y);
ve[y].push_back(x);
}
int k;
scanf("%d",&k);
for(int i = 0;i < k;++i)
{
int num;
scanf("%d",&num);
memset(vis,false,sizeof(vis));
for(int j = 0;j < num;++j)
{
int t;
scanf("%d",&t);
vis[t] = true;
}
bool flag = false;
for(int j = 1;j <= n;++j)
{
if(!vis[j] && !flag){
for(int x = 0;x < ve[j].size();++x)
{
if(!vis[ve[j][x]]){
cout << "NO" << endl;
flag = true;
break;
}
}
}
}
if(!flag){
cout << "YES" << endl;
}
}
return 0;
}


2、L2-026 小字辈

大部分都是孩子找祖宗,用dfs+剪枝做的,我用的bfs,原先祖宗找孩子,每次都要遍历一遍数组,其实预处理一下就可以了,用vector储存孩子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
#define N 100005
vector<int>ve
;
int main()
{
int n;
scanf("%d",&n);
int root;
for(int i = 1;i <= n;++i)
{
int x;
scanf("%d",&x);
if(x == -1){
root = i;
}
else{
ve[x].push_back(i);
}
}
queue<int>que;
que.push(root);
int Front = 0;
int ptr
;
int cnt = 0;
while(!que.empty())
{
int rear = 0;
int tmp
;
Front = 0;
cnt++;
while(!que.empty())
{
int x = que.front();
ptr[Front++] = x;
que.pop();
for(int i = 0;i < ve[x].size();++i)
{
tmp[rear++] = ve[x][i];
}
}
for(int i = 0;i < rear;++i)
que.push(tmp[i]);
}
printf("%d\n",cnt);
for(int i = 0;i < Front;++i)
{
if(i == Front - 1){
printf("%d\n",ptr[i]);
}
else{
printf("%d ",ptr[i]);
}
}
return 0;
}


3、L2-027 名人堂与代金券

这个最后弄并列的时候,有点问题,没得满分

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
using namespace std;
#define N 10005
typedef struct Node{
string s;
int n;
}Node;
Node stu
;
bool cmp(const Node &p,const Node &q)
{
if(p.n == q.n){
return p.s < q.s;
}
else{

4000
return p.n > q.n;
}
}
int main()
{
int n,g,k;
scanf("%d %d %d",&n,&g,&k);
int sum = 0;
for(int i = 0;i < n;++i)
{
string s;
int n;
cin >> s >> n;
stu[i].s = s;
stu[i].n = n;
if(n >= 60 && n < g){
sum += 20;
}
else{
if(n >= g && n <= 100){
sum += 50;
}
}
}
sort(stu,stu + n,cmp);
cout << sum << endl;
int x = 1;
int flag = stu[0].n;
for(int i = 0;i < k;++i)
{
if(flag == stu[i].n){
cout << x << " ";
}
else{
x = i + 1;
cout << x << " ";
flag = stu[i].n;
}
cout << stu[i].s << " " << stu[i].n << endl;
}
for(int i = k;i < n;++i)
{
if(stu[i].n == stu[k - 1].n){
cout << x << " " << stu[i].s << " " << stu[i].n << endl;
}
else break;
}
return 0;
}


在此写出图的三种常用的存储结构:

1.邻接矩阵
int E[110][110];
E[1][2]=1;
E[5][3]=0;

2.邻接链表
#include <vector>
#include <cstdio>
using namespace std;

const int MAXN = 100000;

vector<int> edge[MAXN];

int main()
{
int n, m; //n顶点,m边
for(int i = 0; i < m; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
edge[a].push_back(b);
//edge[b].push_back(a); //如果是无向图要执行这句,来回都要存!
}
return 0;
}

3.前向星
// edges[i].to表示第i条边的终点
// edges[i].next表示与第i条边同起点的下一条边的存储位置
// head[i]表示以i为起点的第一条边存储的位置
typedef struct edge{
int to;
int next;
//int w;     //若有权值
}edge;

edge edges[1010];     // 总共不超过1000条边。
int head[110];        // 不超过100个点。
int cnt;              // 输入的第cnt条边

void init() {         // 初始化。
memset(head, -1, sizeof(head));
cnt = 0;
}

void addEdge(int u,int v) {
//edge[cnt].w = w;
edges[cnt].to = v;
edges[cnt].next = head[u];
head[u] = cnt++;
}

int main() {
int n, t1, t2;
init();
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%d%d", &t1, &t2);
addEdge(t1, t2);
// addEdge(t2, t1);
}
}


树的存储结构:

https://blog.csdn.net/smile_from_2015/article/details/63687696
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: