ACM – ntzyz's blog https://archive.ntzyz.io Mon, 18 Sep 2017 12:20:18 +0000 zh-CN hourly 1 https://wordpress.org/?v=5.8 [CodeForces] Area of Two Circles’ Intersection https://archive.ntzyz.io/2015/11/28/codeforces-area-of-two-circles-intersection/ https://archive.ntzyz.io/2015/11/28/codeforces-area-of-two-circles-intersection/#respond Sat, 28 Nov 2015 03:54:08 +0000 https://blog.dimension.moe/?p=296 继续阅读[CodeForces] Area of Two Circles’ Intersection]]> 精度锅(
http://codeforces.com/contest/600/submission/14533609

#include 

using namespace std;

struct Circle{
    long double x,y;
    long double r;
};

///static long double pi = 3.1415926535897932384626433832795028841971693993751058;

long double calArea(Circle c1, Circle c2) {
    long double d;
    long double s, s1, s2, s3, angle1, angle2;

    d = sqrt((c1.x - c2.x) * (c1.x - c2.x) + (c1.y - c2.y) * (c1.y - c2.y));
    if(d >= (c1.r + c2.r))//两圆相离
        return 0;
    if((c1.r - c2.r) >= d)//两圆内含,c1大
        return acos(-1.0) * c2.r * c2.r;
    if((c2.r - c1.r) >= d)//两圆内含,c2大
        return acos(-1.0) * c1.r * c1.r;

    angle1 = acos((c1.r * c1.r + d*d - c2.r * c2.r) / (2 * c1.r * d));
    angle2 = acos((c2.r * c2.r + d*d - c1.r * c1.r) / (2 * c2.r * d));

    s1 = angle1 * c1.r * c1.r;
    s2 = angle2 * c2.r * c2.r;
    if (c1.r > c2.r)
        s3 = c1.r * d * sin(angle1);
    else
        s3 = c2.r * d * sin(angle2);
    s = s1 + s2 - s3;

    return s;
}
int main() {
    ios::sync_with_stdio(false);
    Circle c1, c2;
    cin >> c1.x >> c1.y >> c1.r;
    cin >> c2.x >> c2.y >> c2.r;
    printf("%.20lf", calArea(c1, c2));
	return 0;
}
]]>
https://archive.ntzyz.io/2015/11/28/codeforces-area-of-two-circles-intersection/feed/ 0
[CodeForces 593A] 2Char https://archive.ntzyz.io/2015/11/05/cf-593a-2char/ https://archive.ntzyz.io/2015/11/05/cf-593a-2char/#respond Thu, 05 Nov 2015 04:20:17 +0000 https://blog.dimension.moe/?p=267 继续阅读[CodeForces 593A] 2Char]]> 可以毫不犹豫的说这场CF是我有屎以来最失败的一场了,比赛期间交了两发A题都是Wrong answer on test 3,最终放弃回去(wan)睡(shou)觉(ji),然后愉快的挂了0而且获得了-108的Rating change,成功创下历史最大跌幅~

睡了一觉冷静了一下之后,开始思考为什么会出现这样的问题……至于这道题,原因还是从思路说吧。

题目不难,题意也不难理解,就是给你一些字符串,你要从中选出几个组成一篇文章,要求就是只出现两个字母并且文章要尽可能长。最后输出文章长度。

我也不是什么机智的人,没想到什么厉害的奇技淫巧,所以思路还是按照原始的题意走的。首先定义了一个结构体,用来表示一个字母出现的次数:

typedef struct {
    char ch;
    int n;
}CH;

然后呢,只要再用一个vector,就能很简单的描述单个字符串中每个字符出现的次数了。为了方便,再写一个typedef:

typedef vector WORD;

现在就可以开始处理题目了。首先是读取所有的字符串,把他转化成上面所写的描述方式,即出现了哪些字母,以及他们出现的次数:

int n;
cin >> n;
vector wd(n);
for (auto& w: wd) {
    string tmp;
    cin >> tmp;
    for (auto& c: tmp) {
        bool flag = false;
        for (auto& i: w) {
            if (c == i.ch) {
                i.n++;
                flag = true;
                break;
            }
        }
        if (!flag) {
            CH t;
            t.ch = c;
            t.n = 1;
            w.push_back(t);
        }
    }
}

按照题意,出现三个或者更多字母的字符串是不可能被计入的,于是就把他们筛掉,留下那些只有两个或者一个字母出现过的字符串。判断一个单词中字母出现的的次数很简单,直接用vector的成员函数size()就可以解决。与此同时,把所有的留下的字符串中出现的字母统计一下,放入all中:

WORD all;
vector sel;
for (auto& w: wd) {
    if (w.size() >= 3) continue;
    sel.push_back(w);
    for (auto& i: w) {
        bool flag = false;
        for (auto& c: all)
            if (c.ch == i.ch) {
                c.n += i.n;
                flag = true;
                break;
            }
        if (!flag) 
            all.push_back(i);
    }
}

经过这样一波处理后,sel内就保存了所有只出现过一个或两个字母的字符串,同时all里面统计了sel中所有的字符串中出现过的所有字母。

这样之后,答案所选的字符串毫无疑问就是all中抽出的一个或两个字母,问题也就在这出现了:比赛期间我没有考虑到所有字符串内都只有一个字母的情况!

int res = 0, tmp;
for (int i = 0; i < all.size(); i++) {
    char c1 = all[i].ch;
    tmp = 0;
    //这个循环是比赛后看到错误原因了才补上的
    for (auto& w: sel) {
        if (w.size() == 1 && w[0].ch == c1)
            tmp += w[0].n;
    }
    res = max(tmp, res);
    for (int j = i + 1; j < all.size(); j++) {
        char c2 = all[j].ch;
        tmp = 0;
        for (auto& w: sel)
            if (w.size() == 1 && (w[0].ch == c1 || w[0].ch == c2))
                tmp += w[0].n;
            else if ((w[0].ch == c1 && w[1].ch == c2) || (w[1].ch == c1 && w[0].ch == c2))
                tmp += w[0].n + w[1].n;
        res = max(tmp, res);
    }
}

出了这个问题只要一组很简单的数据就能轻松爆掉我的代码:

1
a

答案显然是1,但是如果按照我原来的代码,直接就跳出循环了,愉快的输出了0……



王诗钧 11:34:07

·每次比赛后,即使做出来的题,也要试着看看别人的代码,看看他是不是用了一种比你更简洁的,bug更少的方式

·比如昨天的第一道题,你发现有bug,那么是不是你的思路可能不是很简洁,用了比较容易出bug的方法

王诗钧 11:35:22

·这样能够提高你以后写程序的正确率

·思维能力要通过思考题目以及看别人的题解获得

王诗钧 11:37:54

 没有努力就可以超过别人的话,只会出现在别人太菜的情况下

于是我就去看了王诗钧的代码,理解后立马把自己的代码改写了试试,全文:

#include 

using namespace std;

typedef struct {
    char ch;
    int n;
}CH;
typedef vector WORD;

int main()
{
    int n;
    int table[256][256];
    for (auto &i: table)
        fill(i, i + 256, 0);
    cin >> n;
    vector wd(n);
    for (auto& w: wd) {
        string tmp;
        cin >> tmp;
        for (auto& c: tmp) {
            bool flag = false;
            for (auto& i: w)
                if (c == i.ch) {
                    i.n++;
                    flag = true;
                    break;
                }
            if (!flag)
                w.push_back({c, 1});
        }
        if (w.size() >= 3) continue;
        if (w.size() == 1)
            table[w[0].ch][0] += w[0].n;
        else
            table[min(w[0].ch, w[1].ch)][max(w[0].ch, w[1].ch)] += w[0].n + w[1].n;
    }
    int res = 0;
    for (int i = 'a'; i <= 'z'; i++)
        for (int j = i + 1; j <= 'z'; j++)
            res = max(res, table[i][j] + table[i][0] + table[j][0]);
    cout << res ;
    return 0;
}

#待补充理解

不过就算是有了别人的方法,还是WA了一次……最后的两个for循环处z没有等号,然后也是愉快的一组数据爆掉代码……

2
z
z

#待补充整体分析

]]>
https://archive.ntzyz.io/2015/11/05/cf-593a-2char/feed/ 0
[HDU 5504] GT and sequence https://archive.ntzyz.io/2015/10/28/hdu-5504-gt-and-sequence/ https://archive.ntzyz.io/2015/10/28/hdu-5504-gt-and-sequence/#comments Wed, 28 Oct 2015 13:48:10 +0000 https://blog.dimension.moe/?p=241 继续阅读[HDU 5504] GT and sequence]]> 题目好像不难欸,思路很清晰的……但是WA了好久……(摔
题目链接:Problem – 5504
思路很简单,既然题目保证了不会溢出,那就开了long long直接上。
对于所有正数,全部直接乘绝对是最优解。
对于偶数个负数,全部相乘后负号自然就都没了,还是全部乘上去。
最后,奇数个负数,那么就去掉绝对值最小的负数,然后将余下的偶数个奇数全部相乘即可。

这个思路是没问题的是个人都想得到,但是实际写的时候问题颇多。此题出自Bestcoder,当时情况是这样的:(摔

Accepts: 95   Submissions: 1467

_(:з」∠)_

不许吐槽代码里的LoveLive!

代码:

[cc lang=”cpp”]#include

using namespace std;

typedef long long LoveLive;

int main() {
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T–) {
int n;
cin >> n;
vector la, lb;
LoveLive result = 1;
for (int i = 0; i != n; i++) {
LoveLive temp;
cin >> temp;
if (temp > 0)
la.push_back(temp);
else if (temp < 0) lb.push_back(temp); } for (auto i: la) result *= i; if (lb.size() == 0 && la.size() == 0) { cout << 0 << endl; continue; } if (lb.size() == 1 && la.size() == 0) { if (n == 1) { cout << lb[0] << endl; continue; } else { cout << 0 << endl; continue; } } if (lb.size() & 1) { sort(lb.begin(), lb.end()); lb.pop_back(); } for (auto i: lb) result *= i; if (la.size() + lb.size() == n) { cout << result << endl; continue; } else cout << max(static_cast(0), result) << endl; } return 0; } [/cc]

]]>
https://archive.ntzyz.io/2015/10/28/hdu-5504-gt-and-sequence/feed/ 1
[HDU1728] 逃离迷宫 https://archive.ntzyz.io/2015/10/10/hdu1728/ https://archive.ntzyz.io/2015/10/10/hdu1728/#respond Sat, 10 Oct 2015 04:22:32 +0000 https://blog.dimension.moe/?p=185 继续阅读[HDU1728] 逃离迷宫]]> 题目链接 Problem – 1728

最终在王学姐的助攻下A了……不简单啊……

一个深搜居然花了两天 12次提交后才A……

过两天把宽搜版本也顺便改下交掉……

一般深搜没有回溯或多或少都有一些问题
bfs状态记录不全也会有一些问题

嗯……下面贴代码……

#include 

using namespace std;

const int LEFT  = 0;
const int RIGHT = 1;
const int UP    = 2;
const int DOWN  = 3;
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};

char data[150][150];    // Storage the map.
int visited[150][150];  // The counter of how many times has we turned when we reach here
bool found;             // whether the solution is found or not
int m, n, k;            // the same meaning with the problem description

void dfs(int startx, int starty, int endx, int endy, int vec, int c = 0) {
    // Check if we has used up the chance.
    if (c > k) return;
    // Check if we has already reached here before.
    if (visited[starty][startx] < c) return;
    // Mark the position where we are located in.
    visited[starty][startx] = c;

    // Check if we reach (endx, endy) with vec
    int x = startx, y = starty; // (x, y) means where we are.
    for (;;) {
        x += dx[vec];
        y += dy[vec];
        // Check if we reach outside of the map or reach the block in the map.
        if (x < 0 || y < 0 || x >= n || y >= m || data[y][x] == '*')
            break;
        // Check if we reach (endx, endy)
        if (x == endx && y == endy) {
            found = true;
            return;
        }
    }
    // We did not reach the destination directly, so we should turn around at one corner and continue the test.
    x = startx, y = starty; // (x, y) means where we are.
    for (;;) {
        x += dx[vec];
        y += dy[vec];
        // Check if we reach outside of the map or reach the block in the map.
        if (x < 0 || y < 0 || x >= n || y >= m || data[y][x] == '*')
            break;
        // Let's turn at this corner.
        switch (vec) {
        case LEFT:
        case RIGHT:
            dfs(x, y, endx, endy, UP, c + 1);
            if (found) return;
            dfs(x, y, endx, endy, DOWN, c + 1);
            if (found) return;
            break;
        case UP:
        case DOWN:
            dfs(x, y, endx, endy, LEFT, c + 1);
            if (found) return;
            dfs(x, y, endx, endy, RIGHT, c + 1);
            if (found) return;
            break;
        }
        // Mark the place we are now.
        visited[y][x] = c;
    }
}

int main() {
    ios::sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--) {
        cin >> m >> n;
        for (int i = 0; i != m; ++i)
            cin >> data[i];
        int startx, starty, endx, endy;
        cin >> k >> startx >> starty >> endx >> endy;
        startx--, starty--, endx--, endy--;
        // Check if the starting point is the same as target.
        if (startx == endx && starty == endy) {
            cout << "yes" << endl;
            continue;
        }
        found = false;
        for (auto &i: visited)
            fill(i, i + 150, k);
        // The first step has no direction, just try the four direction one by one.
        for (int i = 0; i < 4; i++) {
            visited[starty][startx] = k;
            dfs(startx, starty, endx, endy, i);
            if (found) break;
        }
        if (found)
            cout << "yes" << endl;
        else
            cout << "no" << endl;
    }
    return 0;
}
]]>
https://archive.ntzyz.io/2015/10/10/hdu1728/feed/ 0
[Codeforces] 几场CF后的简单总结~ https://archive.ntzyz.io/2015/09/17/sum-up-for-codeforces/ https://archive.ntzyz.io/2015/09/17/sum-up-for-codeforces/#comments Thu, 17 Sep 2015 06:50:30 +0000 http://blog.dimension.moe/?p=118 继续阅读[Codeforces] 几场CF后的简单总结~]]> 不知不觉间距离黑历史已经快要一个月了。在这段时间里,抱着A水题的心态,报名了每一场cf的比赛,算下来也有四场了。

Codefocres给我最大的感受就是,Div2很适合我们这种萌新去找感觉,难度不是很大,每场下来至少也能A两题,前两题基本都是简单的模拟之类。每场之间的难度也控制的比较稳定,不像某Bestcoder那次突然给我两个图两个树直接打死……同时Codeforces英文的题目读下来也比杭电里的英文题好理解不少~

还有一点不得不说的就是Codeforces是开放所有的测试数据和别人提交的代码的,这就使得调试Wrong Answer代码的时候难度降低了不少,同时你也可以看到那些神触写出的巨牛逼的Python代码(

公开的测试数据

Codeforces的比赛时间是当地时间下午6:30,然而生活在东八区的我们就得熬到深夜0:30,再进行持续两小时的比赛。虽然说平常这个时间点也没开始睡,但是思维的活跃度还是不如中午和下午。而且像我这种强迫症在提交结束后也不愿意立即去睡觉,因为大数据的结果还要等一段时间才出,然后真正睡觉的时候就差不多快4点了……

还有一点……无论如何不要直接互相分享代码!Codeforces有查重!我没试过我会乱说?

最后丢上Codeforces个人页的传送门!

]]>
https://archive.ntzyz.io/2015/09/17/sum-up-for-codeforces/feed/ 1
[Coding] 开源!我的所有AC代码。 https://archive.ntzyz.io/2015/09/02/coding-%e5%bc%80%e6%ba%90%ef%bc%81%e6%88%91%e7%9a%84%e6%89%80%e6%9c%89ac%e4%bb%a3%e7%a0%81%e3%80%82/ https://archive.ntzyz.io/2015/09/02/coding-%e5%bc%80%e6%ba%90%ef%bc%81%e6%88%91%e7%9a%84%e6%89%80%e6%9c%89ac%e4%bb%a3%e7%a0%81%e3%80%82/#respond Tue, 01 Sep 2015 16:03:05 +0000 http://blog.dimension.moe/?p=92 继续阅读[Coding] 开源!我的所有AC代码。]]> 以前经常重装系统导致大量代码的丢失(然而并没有什么重要的代码)……

为了避免这种可啪的事再次发生,我决定……

Accepted-codes – Coding.net

反正就放在coding上吧。我会随着A题的进度把代码贴上去。同时如果有了更快的算法我也会更新掉低效的代码。

]]>
https://archive.ntzyz.io/2015/09/02/coding-%e5%bc%80%e6%ba%90%ef%bc%81%e6%88%91%e7%9a%84%e6%89%80%e6%9c%89ac%e4%bb%a3%e7%a0%81%e3%80%82/feed/ 0
[HDU1008] Elevator https://archive.ntzyz.io/2015/08/06/hdu1008-elevator/ https://archive.ntzyz.io/2015/08/06/hdu1008-elevator/#respond Thu, 06 Aug 2015 04:45:03 +0000 http://blog.dimension.moe/?p=10 继续阅读[HDU1008] Elevator]]> 题目很简单,一次就能A,把代码拉过来测试一下语法高亮~

#include 

int main() {
    int n;
    while (std::cin >> n) {
        if (!n)
            return 0;
        int currFloor = 0;
        int sum = 0, aim;
        while (n--) {
            std::cin >> aim;
            sum += ((currFloor > aim) ? (4) : (-6)) * (currFloor - aim) + 5;
            currFloor = aim;
        }
        std::cout << sum << std::endl;
    }

    return 0;
}
]]>
https://archive.ntzyz.io/2015/08/06/hdu1008-elevator/feed/ 0