CSP - J day9

一. 题目

(1)早安

思路:

(1)cin和scanf读入字符串时遇到空格或换行就停止读入,对于要读入带空格的字符串时,常用             两种方法:

        

// 法一

string s;

getline( cin, s );
// 法二

char s [ 1005 ];

gets(str);


// 获取读入长度

int len = strlen( s );

(2)因为是子串,注意 ' good morning ' 首尾都是g,因此只有第一个 ' good morning ' 要用两个 ' g ' ,后面每个都只要用一个 ' g ' 。

(3)空格也要统计,每一个 ' good morning ' 都需要一个空格

(4)如果先读入一个数字,再接着读入字符串时,需要在读入数字后加上 ' getchar() ' ,用来吃掉回车,否则回车也将当做是一个字符加入到后面的字符串中。

代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int n, t, ng, no, nd, nm, nr, nn, ni, nk, ans;
string s;

int main()
{
	cin >> t;
	getchar();
	while (t --)
	{
		ng = 0, no = 0, nd = 0, nm = 0, nr = 0, nn = 0, ni = 0, nk = 0;
		getline(cin,str);
		for (int i = 0; i < s.length(); i ++)
		{
			if (str[i] == 'g')		ng ++;
			if (str[i] == 'o')		no ++;
			if (str[i] == 'd')		nd ++;
			if (str[i] == 'm')		nm ++;
			if (str[i] == 'r')		nr ++;
			if (str[i] == 'n')		nn ++;
			if (str[i] == 'i')		ni ++;
			if (str[i] == ' ')		nk ++;
		}
		ng --;
		no /= 3, nn /= 2;
		ans = min( min( min(ng, no), min(nd, nm) ), min(nr, nn) );
		ans = min(min(ans, ni), nk);
		cout << ans << endl;
	}
	return 0;
}

二. 专题:图论基础

(1)最短路:dijkstra

1)无优化版本:

#include<bits/stdc++.h>
#define LL long long
using namespace std;

struct node
{
	int v, w;
};

int n, m, s, d[200005], vis[200005];		// 点数 边数 起始点 
vector<node> G[200005];

void dijkstra(int s)                       // 初始时所有点都在一个大集合里
{
	for (int i = 0; i <= n; i ++)          // 多设置一个不存在的点0,后续用于比较
		d[i] = 1e9;                        // 设置初始距离全为无穷大
	d[s] = 0;                              // 源点距离为零
	for (int i = i; i < n; i ++)           // 更新所有点的总次数为n - 1(n也可以)
	{
		int u = 0;
		for (int j = 1; j <= n; j ++)      // 枚举所有点
		{
			if (!vis[j] && d[j] < d[u])    // 找到一个还在集合中并且到原点距离最近的点
				u = j;
			vis[u] = 1;                    // 该点出集合
			for (auto ed : G[u])           // 松弛操作,更新该点所有邻点到原点的最短距离
			{
				int v = ed.v, w = ed.w;
				d[v] = min(d[v], d[u] + w);
			}
		}
	}
}

int main()
{
	cin >> n >> m >> s;
	for (int i = 1; i <= m; i ++)
	{
		int u, v, w;
		cin >> u >> v >> w;
		G[u].push_back({v, w});
	}
	dijkstra(s);
	return 0;
}

2)优先队列优化

         在枚举所有点这个循环中,出现了很多无效操作,已经出集合的点和已经找到最近点但还会继续找下去,因此用大根堆(距离取反)来减少避免循环查找。

#include<bits/stdc++.h>
#define LL long long
using namespace std;

int n, m, s, d[200005], vis[200005];
priority_queue<pair<int, int> > pq;

void dijkstra(int s)
{
	for (int i = 0;i <= n; i ++)
		d[i] = 1e9;
	d[s] = 0;
	pq.push({0, s});
	while (pq.size())
	{
		auto t = pq.top();
		pq.pop();
		int u = t.second;
		if (vis[u])		continue;
		vis[u] = 1;
		for (auto ed : G[u])
		{
			int v = ed.v, w = ed.w;
			if (d[v] > d[u] + w)
			{
				d[v] = d[u] + w;
				pq.push({-d[v], v});
			}
		}
	}
}

int main()
{
	cin >> n >> m >> s;
	for (int i = 1; i <= m; i ++)	
	{
		int u, v, w;
		cin >> u >> v >> w;
		G[u].push_back({v,w})
	}
	dijkstra(s);
	return 0;
}

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值