洛谷100题DAY4

16.P1147 连续自然数和

一段数的和: 首项加末项乘以项数除以二

运用双指针

#include
using namespace std;
const int N = 2e5 + 10;
int m, sum;
int main()
{
	cin >> m;
	for(int i = 1, j = i + 1; i <= m / 2, j <= m / 2 + 1;)
	{
		int sum = (i + j) * (j - i + 1) / 2;
		if(sum < m)j ++;
		else if(sum == m)
		{
			cout << i << ' ' << j << '\n';
			j ++;
		}
		else i ++;
	}
	return 0;
}

17.P1125 [NOIP2008 提高组] 笨小猴

#include
using namespace std;
string s;
map mp;
int main()
{
	cin >> s;
	for(int i = 0; i < s.size(); i ++)
	{
		mp[s[i]] ++;
	}
	int minn = 1001, maxx = 0; 
	for(auto i : mp)
	{
		minn = min(minn, i.second);
		maxx = max(maxx, i.second);
	}
	int k = maxx - minn;
	int flag = 0;
	for(int i = 2; i <= k / i; i ++)
	{
		if(k % i == 0)flag = 1;
	}
	if(flag == 1 || k == 1 || k == 0)
	{
		cout << "No Answer" << '\n';
		cout << 0;
	}
	else 
	{
		cout << "Lucky Word" << '\n';
		cout << k;
	}
	return 0;
}

18.P1605 迷宫

注意return以及恢复现场

#include
using namespace std;
const int N = 1e3 + 10;
int sx, sy, fx, fy, ans, n, m, t; 
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
bool st[N][N];
void dfs(int x, int y)
{
	if(x == fx && y == fy)
	{
		ans ++;
		return;
	}
	for(int i = 0; i < 4; i ++)
	{
		int a = x + dx[i];
		int b = y + dy[i];
		if(!st[a][b] && a >= 1 && a <= n && b >= 1 && b <= m)
		{
			st[a][b] = 1;
			dfs(a, b);
			st[a][b] = 0;
		}
	}
}
int main()
{
	cin >> n >> m >> t;
	cin >> sx >> sy >> fx >> fy;
	st[sx][sy] = 1;
	for(int i = 1; i <= t; i ++)
	{
		int x, y;
		cin >> x >> y;
		st[x][y] = 1;
	}
	dfs(sx, sy);
	cout << ans;
	return 0;
}

19.P1090 [NOIP2004 提高组] 合并果子

用ans来记录每次合并果子的体力值,贪心想每次合并最小的两个为最优解

#include
using namespace std;
priority_queue, greater> pq;
int n, x, ans;
int main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++)
	{
		cin >> x;
		pq.push(x);
	}
	while(pq.size() > 1)
	{
		int a = pq.top();
		pq.pop();
		int b = pq.top();
		pq.pop();
		ans += a + b;
		pq.push(a + b);
	}
	cout << ans;
	return 0;
}

20.P1037 [NOIP2002 普及组] 产生数

知识点:

bitset vis 中

vis.reset( ) 为所有位变为0

先建图,将一个点可以变为的点连上边,从1~9循环每一个数,每一个数能连几条边就有几个true,将true的个数进行统计,循环输入的那几个数字,将每个数字true的个数相乘 

注:考虑数据范围过大使用_int128,但是这个不能直接输出,故使用输出函数

void output(__int128 x)
{
	if(x / 10)output(x / 10);
	putchar(x % 10 + '0');
}
#include
using namespace std;
const int N = 15;
vectorg[N];
string n;
bitset vis;
int k, x, y, ans, cnt[N];
void output(__int128 x)
{
	if(x / 10)output(x / 10);
	putchar(x % 10 + '0');
}
void dfs(int x)
{
	vis[x] = true;
	for(auto i : g[x])
	{
		if(!vis[i])dfs(i);
	}
}

int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> n >> k;
	for(int i = 1; i <= k; i ++)
	{
		cin >> x >> y;
		g[x].push_back(y);
	}
	for(int i = 0; i <= 9; i ++)
	{
		vis.reset();
		dfs(i);
		cnt[i] = vis.count();
	}
	__int128 ans = 1;
	for(auto i : n)
	{
		ans *= cnt[i - '0'];
	}
	output(ans);
	return 0;
}

你可能感兴趣的:(算法)