zoukankan      html  css  js  c++  java
  • ARC001

    ARC001

    Aセンター採点

    • 题意:
    • 题解:
    • 代码:

    Bリモコン

    • 题意:
    • 题解:
    • 代码

    Cパズルのお手伝い

    • 题意:给定 (8 imes 8)的矩阵,让你求是否有八皇后问题放置解,如果有,则输出任意一个解。
    • 题解:就很普通的八皇后问题,dfs回溯寻找,如果有解直接输出然后退出程序,若跑完还没退出,则无解。关键点在于如何dfs,就很普通的坐标移动dfs,用(x)(y)移动回溯,判断则用标记数组,(r[i])表示第几行有,(c[i])表示第几列有,但是斜线较难不过仔细想想也能表示。
    • 代码:
    #include <iostream>
    #include <map>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll mod = 1e9 + 7;
    const ll N = 1e3+9;
    struct node {
        int w, v;
    }a[N];
    int dp[N][N];
    char change[1010];
    char ma[N][N];
    int row[N];
    int col[N];
    int l[N];
    int r[N];
    int L(int i, int j) {
        return i + 8 - j;
    }
    int R(int i, int j) {
        return i + j - 1;
    }
    bool ff = 1;
    int n = 8, m = 8;
    void dfs(int x, int y) {
        if (y > m)y = 1, x++;
        if (x > n) {
            int cnt = 0;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (ma[i][j] == 'Q')cnt++;
                }
            }
            if (cnt == 8) {
                for (int i = 1; i <= n; i++) {
                    cout << (ma[i] +1) <<endl;
                }
                exit(0);
            }
            return;
        }
        if (!r[R(x, y)] && !l[L(x, y)] && !row[x] && !col[y] && ma[x][y] == '.') {
            r[R(x, y)] = 1;
            l[L(x, y)] = 1;
            row[x] = 1;
            col[y] = 1;
            ma[x][y] = 'Q';
            dfs(x, y + 1);
            ma[x][y] = '.';
            r[R(x, y)] = 0;
            l[L(x, y)] = 0;
            row[x] = 0;
            col[y] = 0;
        }
         dfs(x, y+1);
    }
    void solve() {
        for (int i = 1; i <= n; i++) {
            cin >> (ma[i] + 1);
        }
        ff = 1;
        for (int i = 1; i <= n; i++) {
            for (int j = 1;  j <=m; j++) {
                if (ma[i][j] == 'Q') {
                    if (r[R(i, j)])ff = 0;
                    if (l[L(i, j)])ff = 0;
                    if (row[i])ff = 0;
                    if (col[j])ff = 0;
                    col[j] = 1;
                    row[i] = 1;
                    l[L(i, j)] = 1;
                    r[R(i, j)] = 1;
                }
            }
        }
        if (ff) {
             dfs(1, 1);
        } 
            cout <<"No Answer
    ";
    }
    int main() {
        int t = 1;
        while (t--) {
             solve();
        }
    }
    

    Dレースゲーム

    • 题意:在网格图中给出起点和终点,求从起点到终点最短的距离,限制是这个类似跑道,给出(2n)个点,然后要从第(0)层跑到第(n)层,每次给两个点,只能在两点之间跑。
    • 题解:以起点为起始点,然后维护两条线段(l)(r),这两条线段是以起点为起始点,然后(l)(r)的终点分别是能以直线到达跑道端点的最左端点和最右端点,即想象把(l)(r)一直往两边倾斜碰到一点即停。然后,一层层得往下找,如果到了一层,两条线交叉了,说明要么到达的这一层,右边的端点在当前原点的(l)线的左侧,很显然如果在左侧,必然是让当前原点加上(l)改变当前原点的位置是最优的,如果你往中间走或者走(r)都是多走路,如果走弯曲的更是迷惑行为;要么到达的层左边的端点在当前原点的(r)线的右侧,同理让当前原点加上线段(r),答案即是每次更新时所加的线段的长度,最后改变终点坐标限制,左右端点都改成((ex, n + 1)),因为最后只能向着终点走,端点即无用。并且上述遍历结束,当前点一定是直接可以和终点相连,所以直接加上长度即可。
    • 代码:
    #include <iostream>
    #include <cmath>
    
    using namespace std;
    typedef long long ll;
    const int N = 3e5 + 99;
    
    struct Vector {
    	double x, y;
    	Vector (int xx, int yy) : x(xx), y (yy) {}
    	Vector(){}//  
    	double operator * (Vector rhs)const {//叉乘比较方便 
    		return x * rhs.y-y * rhs.x;
    	}
    	Vector operator + (Vector rhs)const {
    		return Vector(x + rhs.x, y + rhs.y);
    	}
    	Vector operator - (Vector rhs)const {
    		return Vector(x - rhs.x, y - rhs.y);
    	}
    	double d() {
    		return sqrt ( x * x + y * y);
    	}
    	void pr() {
    		cout << x << " " << y << endl;
    	}
    }l[N], r[N];
    int main() {
    	int n;
    	cin >> n;
    	int sx, ex;
    	cin >> sx  >> ex;
    	for (int i = 0; i <= n; i++) {
    		cin >> l[i].x >> r[i].x;
    		l[i].y = 1.0 * i;
    		r[i].y = 1.0 * i;
    	}
    	l[n].x = r[n].x = ex;//终点的要改一下 
    	int i ,j = 0;
    	Vector cur(sx, 0), li, ri;
    	double ans= 0;
    	while (j  + 1 <= n) {
    		j = cur.y + 1;
    		i = j + 1;
    		li = l[j] - cur;//所要维护的l线 和r线 
    		ri = r[j] - cur;
    		while (j + 1<= n) {
    			bool changeL = 0;
    			if (li * (l[i] - cur) < 0)li = l[i] - cur, changeL = 1;//叉乘是右手握在纸面上是正 
    			if (ri * (r[i] - cur) > 0)ri = r[i] - cur;//l线和r线向两边撕扯的过程 
    			if (li * ri > 0) {//判断方向有没有出问题 
    				if (changeL) {
    					ans += ri.d();
    					cur = cur + ri;
    				} else {
    					ans += li.d();
    					cur = cur + li;
    				}
    				break;
    			}
    			j++;
    			i++;
    		}
    	}	
    	ans += (cur - l[n]).d();//最后加上答案 
    	printf("%.15lf
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    TP-LINK WR941N路由器研究
    thinkjs初试
    记浏览器帐号登录插件开发遇到的问题
    你被adblock坑过吗?
    web应用,我们需要了解什么?
    算法之合并排序
    算法之插入排序
    算法之初体验
    nodejs学习笔记之网络编程
    炫酷吊炸天的nodeppt
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14314623.html
Copyright © 2011-2022 走看看