UESTC 2014 Summer Training #6 Div.2

  又是只过两水题,不过状态有些回升,也是差点一血.

Problem A  SPOJ AMR11A

  显然的dp?就一抖就想到尝试从(R,C)推到(1,1),正着推的话,只能检查某一种解可不可行(就有人想出了二分+DP的神奇方法。。刚卡过。。不过上界是把所有龙加起来。。不闲麻烦的话。。可以按照贪心的方法先跑一个上界,就每一步选当前最优)

  倒着推,龙的话,就加上,药水的话,减去?不够,和1取最大值;某一个点的f[i][j]就是两种策略取最小值;

  f[i][j] = min{ max(1, f[i+1][j]-s[i][j]) ,  max(1, f[i][j+1]-s[i][j] }

  题外话:  自己是12:24提交的这代码。。不过不是scanf,是cin,然后又提交了一个递推的,还是TLE。。。于是就去写水题,写了水题回来写。。。居然会去写搜索。。主要看大家都没怎么过。。以为不是这么简单的dp 0 0 写了好几个小时,想到了求出那个上界的方法,以后搜索优化也许可以用。。不过对这题没什么帮助,后来又去研究卡时。。总之挂很惨。。差一点一血啊

(记忆化)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>

using namespace std;

const int maxn = 500+10;
const int inf = ~0u >> 2;

int T, r, c, ans;
int f[maxn][maxn], s[maxn][maxn];

int dp(int x, int y)
{
//    cout << "dp " << x << ‘ ‘ << y << endl;
    if(x > r || y > c)    return inf;
    if(f[x][y] != inf)    return f[x][y];
    return    f[x][y] = min(max(dp(x+1, y)-s[x][y], 1), max(dp(x, y+1)-s[x][y], 1));
}

int main()
{
#ifdef LOCAL
    freopen("A.in", "r", stdin);
#endif
    cin >> T;
    while(T--) {
        cin >> r >> c;
        for(int i = 1; i <= r; i++)
            for(int j = 1; j <= c; j++)
                f[i][j] = inf;
        f[r][c] = 1;
        for(int i = 1; i <= r; i++)
            for(int j = 1; j <= c; j++)
                scanf("%d", s[i]+j);
        cout << dp(1, 1) << endl;
    }
    return 0;
}

Problem B  SPOJ AMR11B

 

  大意是给你圆(圆心+半径)、三角形(三点)、正方形(左下角和边长),球出覆盖的点数,只用考虑整数,包括给的数据

  由于数据很小,我们可以求出其外接?的矩形,枚举点再来判定是否在图形内,需要做判重处理。

  圆用x^2+y^2=R^2这种公式就行了,正方形直接枚举的点就是图形内的(包括边界),主要是三角形比较麻烦,需要用到前几天考察过的计算几何的知识(我都还没写解题报告。。)

  判断三个小三角形面积和是否等于大三角形面积。面积的求法只能暂且记住,好像算是线性代数的知识0 0 都没印象。

  S=|(y3-y1)*(x2-x1)-(y2-y1)*(x3-x1)|/2  (在这道题的情况下,就别/2咯)

  奥,把坐标系移动下,c语言数组不好处理负数呢

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <ctype.h>

using namespace std;

const int maxn = 400;

int T, n, cnt;
bool used[maxn][maxn];

void calcSquare()
{
    int x, y, l;
    scanf("%d%d%d", &x, &y, &l);
    x += 100;    y += 100;
    for(int i = 0; i <= l; i++)
        for(int j = 0; j <= l; j++)
            if(!used[x+i][y+j]) {
                used[x+i][y+j] = 1;
                cnt++;
            }
} 

void calcCircle()
{
    int x0, y0, r;
    scanf("%d%d%d", &x0, &y0, &r);
    x0 += 100;    y0 += 100;
    int x = x0-r, y = y0-r, l = 2*r;
    for(int i = 0; i <= l; i++)
        for(int j = 0; j <= l; j++) {
//            if(i == 1 && j == 2)    cout << ( !used[x+i][y+i] && (x+i-x0)*(x+i-x0)+(y+j-y0)*(y+j-y0) <= r*r ) << endl;

//                int a = (x+i-x0)*(x+i-x0)+(y+j-y0)*(y+j-y0), b = r*r;
//                cout << x+i << ‘ ‘ << y+j << ‘ ‘ << a << ‘ ‘ << b << endl;
            if(!used[x+i][y+j] && (x+i-x0)*(x+i-x0)+(y+j-y0)*(y+j-y0) <= r*r) {
//                if( (x+i-x0)*(x+i-x0)+(y+j-y0)*(y+j-y0) > r*r)
                //if(a > b)    continue;
//                cout << "COUNT" << endl;
//                cout << "Change " << x+i << ‘ ‘ << y+j << endl;
                used[x+i][y+j] = 1;
//                cout << "Change " << x+i << ‘ ‘ << y+j << endl;
                cnt++;
            }
        }
}

int area(int x1, int y1, int x2, int y2, int x3, int y3)
{
    //notice real area is this one divide 2
    return abs((y3-y1)*(x2-x1)-(y2-y1)*(x3-x1));
}

void calcTriangle()
{
    int x1, x2, x3, y1, y2, y3;
    scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x3, &y3);
    x1 += 100;    y1 += 100;    x2 += 100;    y2 += 100;    x3 += 100;    y3 += 100;
    int a, b, c, d;
    a = min(x1, min(x2, x3));    b = min(y1, min(y2, y3));
    c = max(x1, max(x2, x3));    d = max(y1, max(y2, y3));
    for(int i = a; i <= c; i++)
        for(int j = b; j <= d; j++)
            if(!used[i][j]) {
                if(area(i, j, x1, y1, x2, y2) + area(i, j, x2, y2, x3, y3) + area(i, j, x1, y1, x3, y3) != area(x1, y1, x2, y2, x3, y3))
                    continue;
                used[i][j] = 1;
                cnt++;
            }
}

int main()
{
#ifdef LOCAL
    freopen("B.in", "r", stdin);
#endif
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        cnt = 0;
        memset(used, 0, sizeof(used));
        while(n--) {
            char c;
            while(!isalpha(c = getchar())) ;
            switch(c) {
                case ‘C‘:    calcCircle();    break;
                case ‘T‘:    calcTriangle();    break;
                case ‘S‘:    calcSquare();    break;
                default:    break;
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}

Problem E  SPOJ AMR11E

  找出第n个幸运数(因子中至少能找出3个不同的质数) 

  由于n比较小,我直接打表出1000个幸运数。。。打表写得比较渣。一开始还写错了。代码不贴咯。

Problem G  SPOJ AMR11G

  就水题。。。判断下有没D  vjudge爬虫代码估计渣了,Sample Input格式有点问题,害得我代码调了很久

//  cin.getline(str, [length], [endcharacter])(会读入endcharacter)

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 100;

int T, N;
char c;

int main()
{
#ifdef LOCAL
    freopen("G.in" , "r", stdin);
#endif
    cin >> T;
    cin.ignore();
    while(T--) {
         {
            char s[maxn];
            cin.getline(s, maxn);
//            cout << s << endl;
//            cin.ignore();
            bool ok = true;
            for(unsigned int i = 0; i < strlen(s); i++)
                if(s[i] == ‘D‘) {
                    ok = false;
                    break;
                }
            if(!ok)    cout << "You shall not pass!" << endl;
            else    cout << "Possible" << endl;
        }
    }
    return 0;
}

Problem J  SPOJ AMR11J

  比较裸的bfs,数据量不大,不用担心什么,关键是策略写对没。

  主要问题在于两个部落同时expand到一点时,会冲突,标记为‘*‘,而bfs是有先后的,除非多线程?

  所以需要延时处理,记录要更新的地点,记录下要更新 为 的标记:另开一个数组,先到先标记,后到发现已标记就置为‘*’

  !!!!这里思路就又错了,逻辑不紧哎。  发现标记不同才置为‘*‘

  否则会出现b.b  ->  b*b

  

(可能是vector降低了效率,跑得比较慢)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
#include<utility>
#include<cstring>

using namespace std;

const int maxn = 500+10;
const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, 1, -1};

typedef pair<int, int> pii;

int T, R, C;
char m[maxn][maxn], ocp[maxn][maxn];
vector<pii>    v;
queue<pii> q;

void update()
{
    for(int i = 0, t = v.size(); i < t; i++) {
        int x = v[i].first, y = v[i].second;
        if(m[x][y] == ‘.‘) {
            m[x][y] = ocp[x][y];
            q.push(make_pair(x, y));
        }
    }
    v.clear();
}

bool can_move(int x, int y)
{
    return x >= 1 && x <= R && y >= 1 && y <= C && m[x][y] == ‘.‘;
}

void bfs()
{
    for(int i = 1; i <= R; i++)
        for(int j = 1; j <= C; j++)
            if(m[i][j] <= ‘z‘ && m[i][j] >= ‘a‘)
                q.push(make_pair(i, j));
    while(!q.empty()) {
        pii tmp = q.front();    q.pop();
        int x = tmp.first, y = tmp.second;
        for(int i = 0; i < 4; i++) {
            int nx = x+dx[i], ny = y+dy[i];
            if(can_move(nx, ny)) {
                if(ocp[nx][ny] && ocp[nx][ny] != m[x][y])
                    m[nx][ny] = ‘*‘;
                else {
                    v.push_back(make_pair(nx, ny));
                    ocp[nx][ny] = m[x][y];
                }
            }
        }
        if(q.empty())    update();
    }
}

int main()
{
#ifdef LOCAL
    freopen("J.in", "r", stdin);
#endif
    cin >> T;
    while(T--) {
        cin >> R >> C;
        while(!q.empty())    q.pop();
        v.clear();
        memset(ocp, 0, sizeof(ocp));
        for(int i = 1; i <= R; i++)
                cin >> (m[i]+1);
        bfs();
        for(int i = 1; i <= R; i++)
            cout << (m[i]+1) << endl;
    }
    return 0;
}

  A题瞄一眼思路就来了,所以直接写的A,无奈犯傻逼,数据量高达500*500=250000 25W啊 TLE得没办法

  然后去跟榜做E、G,E题打表因为自己没读透题,浪费很多时间,这一来一去心态乱了很多。总感觉自己能写A,再去搞没办法又搜索又减枝,反正搞到快4点也一直TLE

  心态真的崩了,一开始以为能做的题,结果卡了这么久,我交了43发。。。彻底蒙了。还有一丝理智,去看J,又慌了!根本不用考虑time的,还去傻逼写优先队来保证每次出队是time最小的,其实就是跟新完一圈又跟新下一圈。不过无伤大雅,有个小错误没时间去发现了。2题GG。rank又垫底。

  心态这玩意,真的不是一两天能改好的,也要看比赛的重要性,多加控制吧。

  自己读题问题也很大的,时常没考虑好就去写。写完样例一跑就傻逼。

  策略:

  问题在于有灵感想出大概思路的时候,不要抢着去写,再读题,再跑样例,理清思路再写代码,最后思考极限数据(也可以一开始就有考虑)

  其实这种策略不是一次想提出,关键是自己执行力度,容易忘掉。

  经常总结才行!

UESTC 2014 Summer Training #6 Div.2

时间: 2024-11-01 14:45:21

UESTC 2014 Summer Training #6 Div.2的相关文章

UESTC 2014 Summer Training #18 Div.2

A.UVALive 6661 题意从1~N中选k个数,和为s的方案数 第一眼搜索,估计错状态量,又去yydp...浪费大量时间 数据很小的,状态数都不会超过2^N...直接dfs就过了 //state二进制表示选取的数 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn = 200; in

UESTC 2014 Summer Training #3 Div.2

(更新中) A:ZOJ 3611 BFS+状态压缩 [题意]:给定一张n*m的图,图上每个点有如下情况:L,R,D,U:代表在该点上只能往它已经给定的方向前进.#,W:不能走到该点.$:走到该点,可以花两分钟得到一分值,然后可以从该点向任意方向走.0:走到该点后可以向任意方向走.然后给你起点和终点坐标,问是否能从起点走到终点,如果能,求出可获得的最大分值以及与之对应达到该最大分值所需的的最小时间花 费.(其中起点和终点坐标可以相同)[知识点]:BFS+状态压缩[题解]:我觉得超级棒的题!真心感觉

UESTC 2014 Summer Training #16 Div.2

虽然被刷了还是要继续战斗下去嗯...就是基础不好,难度相对较大 A.SPOJ AMR10A 点是顺时针给出的,可以在图上画画(脑补也行),连线x-a,x-b(x为选定的一个点,比如第一个点),就把所求面积分成了四部分,a-b左边部分是较容易求出来的, 三角形面积是直接可求,另外两个多边形面积是可以预处理出来的(多个三角形面积和) 反正我是沒想出來...看題解也理解半天,多邊形面積转化为三角形面积和 嗯嗯 #include <iostream> #include <cstdio> #

UESTC 2014 Summer Training #7 Div.2

DAY7一开始状态还行,最高纪录rank7,然后没力气了,一直跌到rank24,问题还是很多呐.昨天总结的问题依然很大. Problem A UVA 12377 就一开始还是慌了,没审清楚题意就去WA了一发. 大意是给你一个数字表示的字符串,最高20位,第一表示有N个质数,后面是其幂的非降序排列,所求能表示的数个数. 简单的排列组合题,不过需要处理出2~END的不同划分,并且满足非降序,用dfs处理即可. 具体就是dfs过程中记录下每一个数字出现的次数,因为相同的次数是不计顺序的,需要在统计时除

UESTC 2014 Summer Training #5 Div.2

持续更新中 B:URAL 1874 三分搜索 [题意]: 给出两条边a,b以及一个墙角,求由这两条边和墙角所构成的四边形的最大面积.[知识点]: 三分搜索[题解]: 将四边形分为两个三角形,其中一个由a,b,以及第三条同时作为墙角斜边的边c,另一个三角形即为墙角与边c构成 则墙角所在的三角形的最大面积为c*c/4,abc变所在的三角形的面积可用海伦公式求出,然后主要是用三分来求这个c,得到c后就可以得到最佳答案了. 还有一种现成的结论...[代码1]: 1 #include <map> 2 #

UESTC 2014 Summer Training #10 Div.2

B.Race to 1 UVA 11762 第一次接触概率dp,完全没想到是dp...没想到能递推出来0 0 首先需要知道 总的期望=每件事的期望×每件事发生的概率 然后可以根据这个来写递推公式,也是dp? 假设不小于x的质数有m个,x的质因子有n个(种 更确切),那么在求X的期望时,可以考虑由他能转移过去的状态转移,X,X/pi p是x的质因子 所以不难得出E(x) = 1+(m-n)/mE(X)+1/msigmaE(X/pi) 注意会加1,因为X转移到后面的情况,就多了一步 //Update

UESTC 2014 Summer Training #11 Div.2

E - Prototype ZOJ 3235 把(d2,0)代入第二个方程可以得到一个方程:经过(d2,0)的抛物线的起点的方程 再把它和第一个方程联立,就能解出两条抛物线的交点,再验算:是否在0~d2范围内,是否在x=d1时会撞到building2 注意可能不需要滑行就能到达(d2,0),先特殊处理这种情况 一开始傻逼理解错题意,后来一直修改又去考虑了不会出现的情况,例如A=0,delta<0,最后才发现了我忘记打sqrt了!!! 这场比赛题略难...就不会做 当时还是比较慌,很怕过不了题,加

UESTC 2014 Summer Training #19

A.UVALive 6161 去迟了,队友已经开始写了,应该是个水题,贴个队友代码 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #inclu

UESTC 2016 Summer Training #1 Div.2

最近意志力好飘摇..不知道坚不坚持得下去.. 这么弱还瞎纠结...可以滚了.. 水题都不会做.. LCS (A) 水 LCS (B) 没有看题 Gym 100989C 水 1D Cafeteria (B) 不会捉 Gym 100989E 水 Gym 100989F 水 Mission in Amman (B) 没看题 Queue (A) 感觉题意理解得有问题啊 1 #include <iostream> 2 #include <cstdio> 3 #include <cstr