首页 > 其他分享 > The 2021 CCPC Guilin Onsite (XXII Open Cup, Grand Prix of EDG

The 2021 CCPC Guilin Onsite (XXII Open Cup, Grand Prix of EDG

时间:2022-11-23 12:14:30浏览次数:67  
标签:Onsite const EDG XXII int ll pos num id

https://codeforces.com/gym/103409/problem/B

B. A Plus B Problem —————数据结构(set)

题意

给你两个n位的数a, b(有前导零), c是a+b的结果(最高位的进位已省略)
q次询问 id pos num代表将第几行的第pos个数修改为num
输出修改后 第三行修改后当前位置的数x 和 三行一共变化的数字的个数cnt

思路

设c数组为每位上a[i]和b[i]的和对10的余数,额外记录一个cn代表后面是否有进位。
分几种情况:
1.就改的数就是原来该位置上的数 那么就没有改变任何一个数 cnt = 0
2.修改前后进位情况一样 不会影响pos位置以外的其他数 cnt = 2,x = 修改后的余数+cn
3.修改前后进位情况不一样 影响前面若干要连续进位的数 即该位置前有几个连续的9的个数tot, cnt = tot + 2 + 1,x = 修改后的余数+cn
然后用set乱搞一下就好了 具体见代码注释

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

const ll N = 1e6 + 10;
const ll M = 5e6 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;

int n, q;
//这样开数组便于后续处理
int a[2][N];
string s1, s2;
set<int>st;

//计算后面是否有进位
int cal_suf(int p) {
	auto it = st.upper_bound(p);
	if (it == st.end()) return 0;
	return (a[0][*it] + a[1][*it]) / 10;
}

//计算前面有多少个连续的9
int cal_pre(int p) {
	auto it = st.lower_bound(p);
	if (it == st.begin()) return p - 1;
	it--;
	return p - (*it);
}

//更新set 和修改的数
void update(int id, int pos, int num) {
	if (a[id][pos] + a[id ^ 1][pos] == 9 && num + a[id ^ 1][pos] != 9)
		st.insert(pos);
	else if (a[id][pos] + a[id ^ 1][pos] != 9 && num + a[id ^ 1][pos] == 9)
		st.erase(pos);

	a[id][pos] = num;
}

void solve()
{
	cin >> n >> q;
	cin >> s1 >> s2;

	s1 = " " + s1;
	s2 = " " + s2;

	for (int i = 1; i <= n; i++) {
		a[0][i] = s1[i] - '0';
		a[1][i] = s2[i] - '0';
                //将余数不是9的位置插入Set中
		if ((a[0][i] + a[1][i]) % 10 != 9) st.insert(i);
	}

	while (q--) {
		int id, pos, num;
		cin >> id >> pos >> num;
		id--;

		int cn = 0;
		cn = cal_suf(pos);
                //前后修改没变化
		if (num == a[id][pos]) {
			cout << (a[id][pos] + a[id ^ 1][pos] + cn) % 10 << " " << 0 << "\n";
			continue;
		}
                
                //修改前后进位相同
		if (a[id][pos] + a[id ^ 1][pos] + cn >= 10 && a[id ^ 1][pos] + num + cn >= 10 || a[id][pos] + a[id ^ 1][pos] + cn < 10 && a[id ^ 1][pos] + num + cn < 10) {
			cout << (num + a[id ^ 1][pos] + cn) % 10 << " " << 2 << "\n";
			update(id, pos, num);
			continue;
		}
                
                //修改前后进位不同
		cout << (num + a[id ^ 1][pos] + cn) % 10 << " " << cal_pre(pos) + 2 << "\n";
		update(id, pos, num);
	}
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int _t = 1;

    //cin >> _t;
	while (_t--)
		solve();
	return 0;
}

K Tax ————bfs + dfs

题意

n(n<=50)个城市 m条双向路 m个城市 第i条路是由第ci个公司造的,第k次进过第x公司造的路就要收费&k * cost[ci]&
每次走的必须是最短路
输出n - 1行 代表从一号城市走到底i + 1号城市最小要收费多少

思路

因为一定要走最短路 所以我们可以先求出最短路 然后很久最短路建一个dag图。
又因为题目给出的n很小 我们可以直接dfs 找最优解 复杂的为O(2^(n / 2))

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

const ll N = 3000 + 5;
const ll M = 5e6 + 10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;

ll n, m, a[N];
ll dis[N], ans[N];
int vis[N], cnt[N];
pair<pair<int, int>, int>e[N];
vector<pair<int, int>>g[N], g2[N];
string s;

void dij(int s) {
	for (int i = 1; i <= n; i++) {
		dis[i] = INF;
		vis[i] = 0;
	}
	priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>>q;
	dis[s] = 0;
	q.push({ dis[s], s });

	while (!q.empty()) {
		auto [w, now] = q.top();
		q.pop();
		if (vis[now]) continue;
		vis[now] = 1;

		for (auto [to, w2] : g[now]) {
			if (dis[to] > dis[now] + 1) {
				dis[to] = dis[now] + 1;
				q.push({ dis[to], to });
			}
		}
	}
}

void dfs(int x, ll val) {
	for (auto [to, c] : g2[x]) {
		cnt[c]++;
		ans[to] = min(ans[to], val + cnt[c] * a[c]);
	    dfs(to, val + cnt[c] * a[c]);
		cnt[c]--;
	}
}

void solve()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		ans[i] = INF;
	for (int i = 1; i <= m; i++)
		cin >> a[i];

	for (int i = 1, u, v, c; i <= m; i++) {
		cin >> u >> v >> c;
		e[i] = { {u, v}, c };
		g[u].push_back({ v, c });
		g[v].push_back({ u, c });
	}

	dij(1);
        //最短路建图
	for (int i = 1; i <= m; i++) {
		int u = e[i].first.first;
		int v = e[i].first.second;
		int c = e[i].second;

		if (dis[u] - dis[v] == 1)
			g2[v].push_back({ u, c });
		if (dis[v] - dis[u] == 1)
			g2[u].push_back({ v, c });
	}

	dfs(1, 0);

	for (int i = 2; i <= n; i++)
		cout << ans[i] << "\n";
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int _t = 1;

    //cin >> _t;
	while (_t--)
		solve();
	return 0;
}

标签:Onsite,const,EDG,XXII,int,ll,pos,num,id
From: https://www.cnblogs.com/yaqu-qxyq/p/16917839.html

相关文章

  • 深度解析KubeEdge EdgeMesh 高可用架构
    摘要:通过高可用特性应用场景、高可用特性使用手册、课题总结、未来展望等四个部分的内容来向大家介绍新版本EdgeMesh的高可用架构。本文分享自华为云社区《KubeEdgeEdgeM......
  • chrome和edge浏览器无法调用摄像头原因及解决办法
    chrome浏览器参考链接:https://blog.csdn.net/xsfqh/article/details/124392334edge浏览器参考链接:https://blog.csdn.net/baidu_31788709/article/details/125652048chro......
  • Edge浏览器额外功能
    1.在百度文库没法复制的时候,网址前面添加:read://或http://read://即可进入阅读模式,然后任意复制。2.将Edge浏览器提升为多线程下载时,在网址输入:Edg......
  • 【USACO2021 February Contest Platinum】Minimizing Edges(图论,贪心)
    传送门设\(d_0(u),d_1(u)\)分别表示\(1\)到\(u\)的偶数长最短路和奇数长最短路。那么即为要求\(G,G'\)的\(d_0,d_1\)都相同。先特判掉二分图的情况,这样任意\(......
  • D. Knowledge Cards
    D.KnowledgeCardsPakChanek,arenownedscholar,inventedacardpuzzleusinghisknowledge.Inthepuzzle,youaregivenaboardwith$n$rowsand$m$colum......
  • [Editorial] 2022 CCPC Guangzhou Onsite
    2022CCPCGuangzhouOnsite大概按题目难度顺序排序。这篇题解可能没那么口胡。GYM104053EElevator相当于每个电梯在\(-x_i\),每次可以把最大的,编号最小的值减一,要求......
  • Chromium内核浏览器(Edge、Chrome)读取串口数据
    chromium内核89版本以上的浏览才支持域名或IP访问时需要HTTPS,localhost没有限制什么是web串行APIWeb串口API为网站提供了一种阅读和写入带有JavaScript的串行设......
  • IEEE LaTeX conference 致谢(acknowledge)被屏蔽
    在IEEELaTeXconference模板有一句话%conferencepapersdonottypicallyuse\thanksandthiscommand%islockedoutinconferencemode.Ifreallyneeded,s......
  • 使用windows切换程序窗口时关闭edg的多个选项卡
    关闭edg浏览器切换程序窗口时展示多个选项卡一、切换程序窗口的方式当使用电脑打开了多个程序时,可以通过按住快捷键alt+tab(或者使用笔记本的触控屏,三指左右滑动快捷手势)......
  • Edge标题栏透明效果消失了
    今天更新Edge107后,发现标题栏的云母透明效果消失了。之前也消失过,后来通过设置在预览功能里面开启圆角选项卡的时候恢复了,今天发现圆角选项卡的方式也一并没了,看着很不习......