0
点赞
收藏
分享

微信扫一扫

Codeforces Round #763 (Div. 2) 部分题解

大师的学徒 2022-01-06 阅读 31

Codeforces Round #763 (Div. 2)

 

A - Robot Cleaner
思维
题意:n*m的地图,一个机器人初始在一个位置,一开始往右下方走,碰到墙壁就改变方向,类似于光的折射(原题有图),每次可以清理和机器人同行或同列的格子,问最少几步清理目标.
 
思路:数据范围很小,模拟一下就可以了,类似于dfs的函数,记录好方向坐标。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #define mem(a,b) memset(a,b,sizeof a)
    using namespace std;
    typedef long long int ll;
    typedef pair<int, int> pii;
    const int N = 105;
    bool flag = false;
    int ans = 0;
    int n, m, sx, sy, ex, ey;//地图尺寸,起点,终点
    //x,y表示当前走到哪里,now表示步数,xx,yy表示上一步的方向坐标
    void dfs(int x, int y,int now,int xx,int yy) {
    	if (x == ex || y == ey|| flag) {
    		ans = now;
    		flag = true;
    		return;
    	}
    	int tx = xx, ty = yy;
    	if (x == n) tx = -1; if (x == 1) tx = 1;
    	if (y == m) ty = -1; if (y == 1) ty = 1;
     
    	dfs(x + tx, y + ty, now + 1, tx, ty);
    	return;
    }
     
    void solve() {
    	cin >> n >> m >> sx >> sy >> ex >> ey;
    	ans = 0; flag = false;
    	dfs(sx, sy, 0, 1, 1);
    	cout << ans << endl;
    }
     
    int main() {
    	ios::sync_with_stdio(false);
    	int t; cin >> t;
    	while(t--)
    	solve();
     
    	return 0;
    }

 
B - Game on Ranges
 
广搜
题意:一个1-n的集合,n个[l,r],每次在区间中选一个数删掉,问完全删完1-n的方法.
 
思路:数据范围很小,所以可以考虑广搜,开始加入区间内所有数入队,每个结点用set维护已经选了哪些数,如果已经被选中直接跳过,最后肯定会有一个可行解。
MLE了一次,sort区间长度从小到大后过了,其实一开始就想到了优化搜索树,没看到题目里说区间可以任意顺序,🤭。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<set>
    #include<queue>
    #define mem(a,b) memset(a,b,sizeof a)
    using namespace std;
    typedef long long int ll;
    typedef pair<int, int> pii;
    const int N = 1e3 + 5;
    typedef struct node {
    	set<int> s;
    	vector<int> p;
    };
    bool cmp(pii a, pii b) {
    	return abs(a.second - a.first) < abs(b.second - b.first);
    }
    void solve() {
    	int n;
    	cin >> n;
    	pii a[N];
    	mem(a, 0);
    	for (int i = 1; i <= n; i++) {
    		int l, r; cin >> l >> r;
    		a[i].first = l;
    		a[i].second = r;
    	}
    	sort(a + 1, a + 1 + n, cmp);
    	
    	vector<int> ans;
    	queue<node> q;
    	//把长度最小的区间派生出的结点们入队
    	for (int i = a[1].first; i <= a[1].second;i++) {
    		node now;
    		now.p.push_back(i);
    		now.s.insert(i);
    		q.push(now);
    	}
     
    	while (!q.empty()) {
    		node now = q.front();
    		q.pop();
    		if (now.p.size() == n) {//得到答案
    			ans = now.p;
    			break;
    		}
    		int cnt = now.p.size() + 1;//cnt表示下一个区间编号,注意要+1
    		int l = a[cnt].first, r = a[cnt].second;
    		for (int i = l; i <= r; i++) {
    			if (now.s.count(i)) continue;//数已经出现过,跳过
    			node temp = now;
    			temp.s.insert(i);//更新
    			temp.p.push_back(i);
    			q.push(temp);
    		}
    	} 
     
     
    	for (int i = 1; i <= n; i++) {
    		cout << a[i].first << " " << a[i].second << " " << ans[i - 1] << endl;
    	}
    	
    }
     
    int main() {
    	ios::sync_with_stdio(false);
    	int t; cin >> t;
    	while (t--)
    		solve();
     
    	return 0;
    }
举报

相关推荐

0 条评论