SDNU ACM-ICPC 2016-2017 Training Weekly Contest 2 【--完结--】

A - An ant's story(思维)

HDU - 3343                    

感觉特别坑的一道题目,只要蚂蚁爬的速度>0,它就能到终点,用到了极限思想?不明觉厉..GG..

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
    int t;
    int a, b, c;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&a,&b,&c);
        if(b > 0)
            cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

B - War Chess(BFS<用到优先队列>)

HDU - 3345                    

BFS好题,当时做的时候不是TLE就是MLE。赛后我重新写还是MLE(喵喵喵?  后来问了一下陆历川大哥,他说得用优先队列,能用优先队列的就别用队列,然后给我发了个优先队列的讲解博客地址。又学到了新东西啊..

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int MAX = 105;
int n, m, v;
int dir[][2] = {0,1,1,0,-1,0,0,-1};
char mapa[MAX][MAX], newa[MAX][MAX];
bool vis[MAX][MAX], eme[MAX][MAX];
struct node
{
    int x, y, v;
    bool operator < (const node &a) const
    {
        return v < a.v;//v大的优先
    }
} q, p;

bool ok()
{
    if(p.x < 0 || p.y < 0 || p.x >= n || p.y >= m) return false;
    if(!p.v || vis[p.x][p.y] || mapa[p.x][p.y] == '#' || mapa[p.x][p.y] == 'E') return false;
    if(mapa[p.x][p.y] == '.' || mapa[p.x][p.y] == 'P') p.v -= 1;
    else if(mapa[p.x][p.y] == 'T') p.v -= 2;
    else if(mapa[p.x][p.y] == 'R') p.v -= 3;
    if(p.v < 0) return false;
    if(eme[p.x][p.y]) p.v = 0;
    return true;
}

void bfs()
{
    priority_queue<node> Q;
    Q.push(q);
    while(!Q.empty())
    {
        q = Q.top();
        Q.pop();
        for(int i = 0; i < 4; ++i)
        {
            p.x = q.x + dir[i][0];
            p.y = q.y + dir[i][1];
            p.v = q.v;
            if(ok())
            {
                vis[p.x][p.y] = 1;
                if(mapa[p.x][p.y] != 'P') newa[p.x][p.y] = '*';
                Q.push(p);
            }
        }
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(vis, 0, sizeof(vis));
        memset(eme, 0, sizeof(eme));
        scanf("%d%d%d",&n, &m, &v);
        for(int i = 0; i < n; ++i)
        {
            scanf("%s",mapa[i]);
            strcpy(newa[i], mapa[i]);
        }
        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
            {
                if(mapa[i][j] == 'Y')
                {
                    vis[i][j] = 1;
                    q.x = i;
                    q.y = j;
                    q.v = v;
                }
                if(mapa[i][j] == 'E')
                {
                    if(i - 1 >= 0) eme[i-1][j] = 1;
                    if(j - 1 >= 0) eme[i][j-1] = 1;
                    if(i + 1 < n) eme[i+1][j] = 1;
                    if(j + 1 < m) eme[i][j+1] = 1;
                }
            }
        bfs();
        for(int i = 0; i < n; ++i)
            cout << newa[i] << endl;
        cout << endl;
    }
    return 0;
}

C - Lucky Number(基础)

HDU - 3346                    

这个不多说了,又是抢的一血。额..当时有点激动漏了个条件(当然样例是不会让你看出来的,细心一点就好了。

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

int main()
{
    int t, n, ans, ans2;
    while(~scanf("%d",&t))
    {
        while(t--)
        {
            ans = ans2 = 0;
            scanf("%d",&n);
            if(n % 8 == 0) cout << "Lucky number!" << endl;
            else
            {
                int tem = n;
                while(tem)
                {
                    int qq = tem % 10;
                    ans += qq;
                    tem /= 10;
                    ans2 = ans2 + qq*qq;
                }
                if(ans % 8 == 0 || ans2 % 8 == 0)
                    cout << "Lucky number!" << endl;
                else cout << "What a pity!" << endl;
            }
        }
    }
    return 0;
}


D - Calculate the expression(模拟)

HDU - 3347                    

模拟呀..今下午自己写了会,用了不少STL的东西,后来将表示数字的字符转换为数字时我想到了atoi函数,然而这个函数对string不适用,想着改为char数组后再用这个函数吧,改着改着把自己改迷糊了..去听完报告回来后全换为char数组,结果TLE了(如果用stringstream不就直接弄死我..问了问我兄弟,他说在打游戏让我去他博客找找看(→_→你很棒棒哦  对比后感觉自己写的略微“高级”,然后我把“高级”部分改为朴素的if -- else if然后就过了,噫,看来能A题的代码才是好代码。

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
char s[105];
char k[25];
int main()
{
    int t, n, flag, tem, ans;
    scanf("%d",&t);
    while(t--)
    {
        flag = 1;
        ans = 0;
        map<string, int> ss;
        scanf("%d",&n);
        //cout << "n=  " << n << endl;
        for(int i = 1; i < n; ++i)
        {
            scanf("%s = %d",s, &tem);
            ss[s] = tem;
            //cout << "s= " << s << "  tem= " << tem << endl;
            //cout << "???" << endl;
        }
        while(1)
        {
            scanf("%s",s);
            tem = 0;
            if(s[0] >= '0' && s[0] <= '9')//是正数 数字
            {
                for(int i = 0; i < strlen(s); ++i)
                {
                    tem *= 10;
                    tem += (s[i] - '0');
                }
                if(flag == 0) ans = ans - tem;
                else ans = ans + tem;
            }
            else if(s[0] == '-')  //这里注意一下 表达式中出现-号一定是常数 (我之前还以为会有 1 + -aa的情况..
            {
                for(int i = 1; i < strlen(s); ++i)
                {
                    tem *= 10;
                    tem += (s[i] - '0');
                }
                if(flag == 1) ans = ans - tem;
                else ans = ans + tem;
            }
            else if(flag == 0)
                ans = ans - ss[s];
            else
                ans = ans + ss[s];
            scanf("%s",k);
            if(k[0] == '=') break;
            if(k[0] == '+') flag = 1;
            else flag = 0;
        }
        scanf("%s",k);//处理最后剩下的"?"
        //cout << "ans= " << ans << endl;
        cout << ans << endl;
    }
    return 0;
}


写完这篇博客的第二天发现了个有趣的函数——c_str(),这个函数会生成一个const char*指针,指向以空字符终止的数组,有了它我们就可以对string使用atoi函数了。马上去写了一下,觉得爽的同时也觉得自己还是图样图森破。

(我发现的问题,那些前辈们肯定早就知道了,还有的早就在函数库里添加了相应的函数,只是我不知道而已( ̄ε(# ̄)☆╰╮( ̄▽ ̄///) 最后再说一句——STL大法好

AC代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <sstream>
using namespace std;
int main()
{
    int t, n, tem, flag, ans;
    string s, stem;
    scanf("%d",&t);
    while(t--)
    {
        map<string, int> num;
        scanf("%d",&n);
        for(int i = 1; i < n; ++i)
        {
            cin >> s;
            scanf(" = %d",&tem);
            num[s] = tem;
            //cout << s << "  " << tem;
        }
        getchar();//接收一个换行符 这里要注意一下
        getline(cin, stem);
        stringstream ss(stem);
        ans = 0;
        flag = 1;
        while(ss >> s)
        {
            if(s == "=") break;
            if(s == "-") flag = -1;
            else if(s == "+") flag = 1;
            else
            {
                if(isalpha(s[0]))
                {
                    tem = num[s];
                }
                else
                {
                    tem = atoi(s.c_str());//666
                }
                ans += (tem*flag);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

E - coins(贪心)

HDU - 3348                    

贪一贪。(代码写的通俗易懂,至于别人的空间复杂度低的我也不去管了,反正能A题的代码都是好代码(⊙v⊙)        明明很好解决的问题,却只有我和我兄弟做出来了。啧啧啧,队友瑕还说这个和上次做的多重背包的很像,受背包毒害不浅啊..还有通过这次训练,我决定我来作主代码手,毕竟我刷的(基础)题多,见识的(无用)知识点多,还有单身19年+的手速。
AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int a[5], b[5];  //面值为1 5 10 50 100的钞票个数
int main()
{
    int t, p, ans1, ans2;;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&p);
        ans1 = ans2 = 0;
        for(int i = 0; i < 5; ++i)
            scanf("%d",&a[i]);
        for(int i = 0; i < 5; ++i)
            b[i] = a[i];
        int tem = p;
        while(tem >= 100 && a[4])
        {
            tem -= 100;
            a[4]--;
            ans2++;
        }
        while(tem >= 50 && a[3])
        {
            tem -= 50;
            a[3]--;
            ans2++;
        }
        while(tem >= 10 && a[2])
        {
            tem -= 10;
            a[2]--;
            ans2++;
        }
        while(tem >= 5 && a[1])
        {
            tem -= 5;
            a[1]--;
            ans2++;
        }
        while(tem >= 1 && a[0])
        {
            tem -= 1;
            a[0]--;
            ans2++;
        }
        if(tem > 0)
        {
            ans2 = ans1 = -1;
            cout << "-1 -1" << endl;
        }
        else
        {
            while(b[0] + b[1] * 5 + b[2] * 10 + b[3] * 50 < p)
            {
                p -= 100;
                ans1++;
            }
            while(b[0] + b[1] * 5 + b[2] * 10 < p)
            {
                p -= 50;
                ans1++;
            }
            while(b[0] + b[1] * 5 < p)
            {
                p -= 10;
                ans1++;
            }
            while(b[0] < p)
            {
                p -= 5;
                ans1++;
            }
            ans1 += p;
            cout << ans2 << " " << ans1 << endl;
        }
    }
    return 0;
}


F - lazy gege(数学)

HDU - 3349                    

平面几何,找长方形的重心—>看正方形的对角线长度和长方形中较短的边的关系,一共有三种情况,自己画个图就很好理解了。计算几何主要就是看思维了,代码实现并没有什么难度,注释的挺详细了,注意一下三个if的顺序。

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
    int t;
    double l, a, b, ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf",&l,&a,&b);
        if(a > b) swap(a, b);        //保证a为长方形的较小边
        double tem = sqrt(2.0) * l;  //正方形的对角线长度
        if(a < tem) ans = a*a/4.0;   //放在正方形上的部分为等腰△
        else if(a > tem && a < 2.0*tem) ans = l*l - (tem - a/2)*(tem - a/2);  //正方形面积减去等腰三角形面积
        else ans = l*l;       //覆盖正方形
        printf("%.4lf\n",ans);
    }
    return 0;
}


G - #define is unsafe(模拟)

HDU - 3350                    

用栈实现的模拟题,这里我用vector数组模拟了个栈。

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
struct node
{
    int val;//值
    int add;//+的次数
};
//用vector实现模拟栈的FILO
vector<node> ans;//数值栈
vector<char> sig;//符号栈
int main()
{
    int T;
    string str;
    node tem, tem2;
    scanf("%d",&T);
    while(T--)
    {
        cin >> str;

        //不要忘记初始化
        tem.val = tem.add = 0;
        ans.clear();
        sig.clear();

        for(int i = 0; i < str.length(); ++i)
        {
            //逐字扫描,只有'('、'+'、','、')'和数字是有用的
            //"MAX"不做处理
            //优先级:'(' > '+' > ',' > ')'
            switch(str[i])
            {
            case '(':
                sig.push_back(str[i]);
                tem.val = tem.add = 0;
                break;
            case '+':
                ans.push_back(tem);
                sig.push_back(str[i]);
                tem.val = tem.add = 0;  //每次push后都要初始化tem
                break;
            case ',':
                while(!sig.empty() && sig.back() == '+')
                {
                    tem2 = ans.back();
                    tem.val += tem2.val;
                    tem.add += tem2.add + 1;
                    ans.pop_back();
                    sig.pop_back();
                }
                ans.push_back(tem);
                sig.push_back(str[i]);
                tem.val = tem.add = 0;  //初始化tem
                break;
            case ')':
                while(!sig.empty() && sig.back() == '+')
                {
                    tem2 = ans.back();
                    tem.val += tem2.val;
                    tem.add += tem2.add + 1;
                    ans.pop_back();
                    sig.pop_back();
                }
                tem2 = ans.back();
                if(tem.val < tem2.val)
                {
                    tem.val = tem2.val;
                    tem.add = tem2.add*2 + tem.add;
                }
                else
                {
                    tem.add = tem.add*2 + tem2.add;
                }
                sig.pop_back();
                sig.pop_back();
                ans.pop_back();
                break;
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                tem.val = tem.val*10 + str[i] - '0';
                break;
            }
        }
        while(!sig.empty() && sig.back() == '+')
        {
            tem2 = ans.back();
            tem.val += tem2.val;
            tem.add += tem2.add + 1;
            ans.pop_back();
            sig.pop_back();
        }
        cout << tem.val << " " << tem.add << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值