zoukankan      html  css  js  c++  java
  • codeforces1301D Time to Run 模拟

    网址:https://codeforces.com/contest/1301/problem/D

    题意:

    给一个$n*m(1 leq n,m leq 500)$的格子构成的图,这些格子之间都有两条互为反向的边联通,一条边只能走一次,求从左上角的点开始能不能恰好走完$k$条边?输出时,按照以下格式输出:每行输出一个二元组$a,b$,$a$是次数,$b$是一个只含有$U,D,L,R$的字符串且长度小于$4$,意思是将会从这个点出发按顺序执行$a$次$b$中字符指代的方向,这称为一条指令,在走这$k$条路时最多只能执行$3000$条指令,否则认为不能走完。

    题解:

    只要$k$小于这些边的数量,就一定能走完,但是因为有指令数量限制,所以就需要尽可能规律地走,就可以将这些重复走法合并成一条指令。然后怎么走会规律呢?我们考虑一种尽可能多直线的走法。先向右横着走$m-1$格,然后向左$m-1$格,然后向下一格,然后可以这样子走$n-1$个循环。然后向右$m-1$格,同样的道理走纵向。总共只需要走$(3*m-3)*(n-1)+(3*n-3)+2$条边。

    然后我们为了降低编程难度,先编程算出所有的规律的路径保存起来,然后就找长度是刚好是$k$的就指令就可以了,具体看代码。

    AC代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5;
    typedef long long ll;
    vector<pair<int, string> >v, ans;
    #define pb push_back
    #define mp make_pair
    #define len(x) (x.first*x.second.size())
    void init(int n, int m)
    {
    	v.clear();
    	ans.clear();
    	for (int i = 1; i <= n; ++i)
    	{
    		if (i < n)
    		{
    			v.push_back(mp(m - 1, "R"));
    			v.push_back(mp(m - 1, "L"));
    			v.push_back(mp(1, "D"));
    		}
    		else
    			v.push_back(mp(m - 1, "R"));
    	}
    	for (int i = 1; i <= m; ++i)
    	{
    		if (i < m)
    		{
    			v.push_back(mp(n - 1, "U"));
    			v.push_back(mp(n - 1, "D"));
    			v.push_back(mp(1, "L"));
    		}
    		else
    			v.push_back(mp(n - 1, "U"));
    	}
    }
    int solve()
    {
    	int n, m, k;
    	scanf("%d%d%d", &n, &m, &k);
    	if (k > 4 * n * m - 2 * m - 2 * n)
    		return printf("NO
    "), 0;
    	init(n, m);
    	for (auto i : v)
    	{
    		if (k > len(i))
    		{
    			if (i.first)
    				ans.push_back(i), k -= len(i);
    		}
    		else
    		{
    			int di = k / i.second.size();
    			int le = k % i.second.size();
    			if (di)
    				ans.push_back(mp(di, i.second));
    			for (int j = 0; j < le; ++j)
    				ans.push_back(mp(1, string(1, i.second[j])));
    			break;
    		}
    	}
    	printf("YES
    %d
    ", ans.size());
    	for (auto i : ans)
    		printf("%d %s
    ", i.first, i.second.c_str());
    	return 0;
    }
    int main()
    {
    	int t = 1;
    	//scanf("%d", &t);
    	while (t--)
    		solve();
    	return 0;
    }
    
  • 相关阅读:
    Oracle 实现自动递增的功能
    解决升级chrome导致“Silverlight ”插件失效
    解决笔记:转载篇
    MSP432在CCS上新建工程,导入固件库
    操作系统复习文档
    数据结构
    数据结构
    蓝桥
    ACM山东工商 数据结构与算法 第3章 双向栈的操作
    ACM山东工商 栈和队列算法练习
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/12323447.html
Copyright © 2011-2022 走看看