UCF Local Programming Contest 2015

比赛链接

A题 解题思路:


查找是否和 17 和 18 这两个数字:
1. 如果两个都存在,输出both
2. 如果都不存在,输出none
3. 如果存在17,那么输出zack
4.如果存在18,那么输出mack


代码:


#include
#include
#include
#include
#include
#include 

using namespace std;

char a[10][10];
int ans[100];

int main(){
    int t;
    scanf("%d",&t);
    for (int j = 1; j <= t; j++){
        int n = 10;
        int x = 0, y = 0;
        for (int i = 0 ; i < n; i++){
            scanf("%d",&ans[i]);
            if (ans[i] == 17){
                x = 1;
            }
            if (ans[i] == 18){
                y = 1;
            }
        }
        for (int i = 0; i <n; i++){
            if (i == n - 1){
                printf("%d",ans[i]);
            }
            else printf("%d ",ans[i]);
        }
        printf("\n");
        if (x && y){
            printf("both\n");
        }
        else if (!x && !y){
            printf("none\n");
        }
        else if (x == 1){
            printf("zack\n");
        }
        else{
            printf("mack\n");
        }
        printf("\n");
    }
    return 0;
}




B题 解题思路:


和A题类似

  1. 如果a b c 的总数 > d e f 的总数,并且 奖牌的质量也高于,那么输出 both
  2. 如果数量大于,那么输出count
  3. 如果质量大于,那么输出color
  4. 否则输出none


代码:


#include
#include
#include
#include 
#include
#include

using namespace std;

char a[10][10];
int ans[100];

int main(){
    int t;
    scanf("%d",&t);
    for (int j = 1; j <= t; j++){
        int a, b, c, d, e, f;
        scanf("%d%d%d%d%d%d",&a, &b,&c, &d, &e, &f);
        int res = a + b + c;
        int num = f +d + e;
        int x = 0, y = 0;
        if (res > num){
            x = 1;
        }
        if (a > d || (a >= d && b > e) || (a == d && b == e && c > f)){
            y = 1;
        }
        printf("%d %d %d %d %d %d\n",a,b,c,d,e,f);
        if (x && y){
            printf("both\n");
        }
        else if (!x && !y){
            printf("none\n");
        }
        else if (x){
            printf("count\n");
        }
        else{
            printf("color\n");
        }
        printf("\n");
    }
    return 0;
}



C题 解题思路:


C题也是道水题,只要当前的蛋糕数小于等于来的人数,那么就 * 2,然后排着输出即可。


代码:


#include 
#include 
#include 
#include 

using namespace std;


int main(){
    int t;
    scanf("%d",&t);
    int q = 1;
    while(t--){
        int n, m;
        scanf("%d%d",&n,&m);
        int k;
        printf("Practice #%d: %d %d\n",q,n,m);
        scanf("%d",&k);
        for (int i = 0; i < k; i++){
            int p;
            scanf("%d",&p);
            while (p >= m){
                m *= 2;
            }
            m -= p;
            printf("%d %d\n",p,m);
        }
        q++;
        printf("\n");
    }
    return 0;
}


D题 解题思路:


D题我感觉是ABCDEFG里最难的(可能是当时脑子糊涂了)
首先肯定是每次更新最小值,我们使用最小值去购买,然后主要是计算糖比较麻烦(想哭)
首先我们用我们需要的糖与我们剩下的糖做比较,如果剩下的 >= 需要的那么就不必购买,随后我们用剩下的 -= 需要的即可,如果是 > , 那么我们需要的减去剩下的,然后再进行计算。


代码:


#include 
#include 
#include 

using namespace std;


int main(){
   int  t;
   scanf("%d",&t);
   for (long long  i = 1; i <= t; i++){
        long long  d, n, s;
        scanf("%lld%lld%lld",&d,&n,&s);
        long long  mn = 1e9;
        long long  ms = 1e9;
        long long  b, c;
        long long  res = 0;
        long long  m = 0;
        int a ;
        for (long long  j = 1; j <= d; j ++){
            scanf("%d%lld%lld",&a,&b,&c);
            if (b < mn){
                mn = b;
            }
            if (c < ms){
                ms = c;
            }
            res += n * a *mn;
            if (m >= a * n *ms){
                m -= a * n * ms;
                continue;
            }
            else{
                long long  result = a * s  - m;
                m = 0;
                if (result % 80 == 0){
                    res += result / 80 * ms;
                }
                else{
                    m += (80 - (result % 80));
                    res += ms * (result/80 + 1);
                }

            }

        }
        cout<<res<<endl;
   }
   return 0;
}


E题 解题思路:


稍微有点麻烦,首先我们进行分类:

  1. 如果r >= d / sqrt(2) , 那么正方形在圆中,我们输出正方形面积即可
  2. 如果的d >= 2 * r ,那么圆在正方形中,输出圆面积即可
  3. 然后就是最麻烦的情形,首先我们可以知道r 与 d / 2,因此我们可以求出来 三角形的面积,就是 sqrt(r * r - d * d / 4) * d / 2 *4 (因为有4个,所以我们乘4),然后我们可以知道 sin a = sqrt(r * r - d * d / 4) / r ,然后利用反函数,求出弧度,a = asin(sqrt(r * r - d * d / 4) / r ) , 然后利用弧度转换为角度的计算(代码),然后求出相应的角度,根据扇形公式求出面积。


代码:


#include 
#include 
#include 
#include 
#include 

using namespace std;


const double P = 3.14159265358979;

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        double d, r;
        double res ;
        scanf("%lf%lf",&d,&r);
        double d1 = d * 1.0/sqrt(2);
        if (d1 <= r){
            res = d * d;
            printf("%.2f\n",res);
        }
        else if (d >= 2 * r){
            res = P * r * r;
            if (res * 100 - (int)(res * 100) >= 0.5) res += 0.005;
            printf("%.2f\n",res);
        }
        else{
            double k = (sqrt(r * r - (d * 1.0 / 2) * (d * 1.0/2)) * d * 1.0 / 2) * 4; // 三角形面积
            double a = sqrt(r * r - (d * 1.0 / 2) * (d * 1.0/2)) / r; // 求出sin 的比值
            double b = asin(a); // 求出相应的弧度
            b = b * 360/(2*P);  // 求出相对应的角度
            b = 90 - 2 * b; // 求出扇形对应的角度
            double l = b * P * r * r /360 ; // 求出扇形的面积
            res = l * 4 + k;
            if (res * 100 - (int)(res * 100) >= 0.5) res += 0.005;
            printf("%.2f\n",res);
        }
    }
    return 0;
}


F题 解题思路:


给予字符串,其中 a, e, i, o, y 是原因,其他的为辅音,要求元音辅音交叉存在(偶数),其实就是两种情况:

  1. 全是问号 ? 那么我们肯定是元音辅音交叉 (我们首先让元音,然后辅音, 再一种辅音,一种元音)
  2. 然后另一种是不全是问号, 那么我们从不是问号的字母开始,左右所得的数相乘就OK,如果当前是元音,那么下个肯定是辅音,循环判断就OK。


代码:


#include
#include
#include
#include
#include
#include

using namespace std;

set <char> ss;

vector<int> mul(vector<int> &A, int b)
{
    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size() || t; i ++ )
    {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }

    return C;
}

vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}

int main(){
    ss.insert('a');
    ss.insert('e');
    ss.insert('i');
    ss.insert('o');
    ss.insert('u');
    ss.insert('y');
    long long t;
    scanf("%lld",&t);
    long long pp = 1;
    while(t--){
        int p; // 1表示辅音, 0 代表 元音
        char st[10001];
        scanf("%s",st);
        int x = 0;
        int y = 0;
        int qq = 0;
        int n = strlen(st);
        for (int i = 0; i < n; i++){
            if (st[i] != '?'){
                y = i;
                x = 1;
                break;
            }
        }
        if (x == 0){
            vector <int> c;
            c.push_back(1);
            for (int i = 0 ; i < strlen(st); i++){
                if (i % 2 == 0)
                    c = mul(c,20);
                else{
                    c = mul(c,6);
                }
            }
            vector <int> d;
            d.push_back(1);
            for (int i = 0; i < strlen(st); i ++){
                if (i % 2 == 0){
                    d = mul(d,6);
                }
                else{
                    d = mul(d,20);
                }
            }
            c = add(c,d);
            printf("String #%lld: ",pp);
            for (int i = c.size() - 1 ; i >= 0 ; i--){
                printf("%d",c[i]);
            }
            printf("\n");
        }
        else{
            // y
            vector <int> c;
            c.push_back(1);
            int q = 0;
            if (ss.count(st[y]) == 0){  // p  = 1是 辅音
                p = 1;
                q = 1;
            }
            else{
                p = 0;
                q = 0;
            }
            for (int i = y + 1; i < strlen(st); i++){
                if (st[i] == '?'){
                    if (p == 1){
                        p = 0;
                        c = mul(c,6);
                    }
                    else{
                        p = 1;
                        c = mul(c,20);
                    }
                }
                else{
                    if (ss.count(st[i]) == 0){
                        if( p == 1){
                            qq = 1;
                            break;
                        }
                        else{
                            p = 1;
                            continue;
                        }
                    }
                    else{
                        if (p == 0){
                            qq = 1;
                            break;
                        }
                        else{
                            p = 0;
                            continue;
                        }
                    }
                }

            }
            for (int i = y - 1; i >= 0;i--){
                if (st[i] == '?'){
                    if (q == 1){
                        q = 0;
                        c = mul(c,6);
                    }
                    else{
                        q = 1;
                        c = mul(c,20);
                    }
                }
                else{
                    if (ss.count(st[i]) == 0){
                        if (q == 1){
                            qq = 1;
                            break;
                        }
                        else{
                            q = 1;
                            continue;
                        }
                    }
                    else{
                        if (q == 0){
                            qq = 1;
                            break;
                        }
                        else{
                            q = 0;
                            continue;
                        }
                    }
                }
            }
            if (qq == 1){
                printf("String #%lld: 0\n",pp);
            }
            else{

                printf("String #%lld: ",pp);
                for (int i = c.size() - 1; i >= 0; i --){
                    printf("%d",c[i]);
                }
                printf("\n");
            }

        }
        pp++;
        printf("\n");

    }
    return 0;
}
G题 解题思路:


首先给予 a, n,代表个数和图的大小,我们可以想,一个数可以从左上角到右下角,必须有一条路径,所以我们可以存入的数量是(n - 1)* (n - 1),因此用a 与 (n - 1)* (n - 1) + 1的大小,如果 大于,那么impossible,然后另外的情况就是 a * (n - 1) * 2 ,其实( n - 1) * 2 就是路径的长度。


代码:


#include 
#include 
#include 

using namespace std;

char ans[10][10];

int main(){
   int t;
   scanf("%d",&t);
   for (int i = 1; i <= t; i++){
        int a, n;
        scanf("%d%d",&a,&n);
        if (a > (n - 1)*(n - 1) + 1){
            printf("Grid #%d: impossible\n",i);
        }
        else{
            printf("Grid #%d: %d\n",i,a * (2 * (n - 1)));
        }
       printf("\n");
   }
   return 0;
}

H题 解题思路:


首先我的思路是从第二行到倒数第二行排着判断上面的点是否是#,如果是#那么我们肯定要对当前的位置进行盖章,所以排着遍历,注意边界的值,然后完美wa掉。(因为其中有些情况不太好确定)

正常的是搜索,我们搜索#点,但是同时我们应该处理边界的情况。

大体思路,dfs,我们从2 ,2 开始搜索,判断十字章的位置是否能够改变,然后求出最小值,最后进行些剪枝,最后我们输出即可。


代码:


#include 
#include 
#include 
#include 
#include 

using namespace std;

const int N = 100010;

char g[10][10]; // 存储点

int mi, n, m;

void dfs(int x, int y, int ans, int res){ // ans 已经点了多少,res 指还剩多少点
    if (res == 0){ 
        mi = min(ans,mi);
        return ;
    }

    if((res - 1)/5 + 1 + ans >= mi) return ; // 如果当前走过的点 + 还需要最少走的点 已经超过了最小值
    if (x <= 1 || x >= n || y <= 1 || y >= m) return ; // 边界值处理

    char tp[7];  // 存储5个需要改变的点      
    tp[0] = g[x - 1][y];tp[1] = g[x][y];
    tp[2] = g[x + 1][y];
    tp[3] = g[x][y - 1];
    tp[4] = g[x][y + 1];

    int num = 0;
    int p = 1;
    
    for (int i = 0; i < 5; i++){ // 判断是否有不可改变的点
        if (tp[i] == '#') num++;  
        if (tp[i] == '.') p = 0;
    }


    if (p && num){
        g[x][y] = g[x - 1][y] = g[x + 1][y] = g[x][y + 1] = g[x][y - 1] = '@';  // 让以后印章的位置也可以选取当下点
        if (y + 1 < m) dfs(x,y + 1, ans + 1, res - num);
        else dfs (x + 1,2, ans + 1, res - num);
        g[x - 1][y] = tp[0]; // 回溯 ,还原现场 (这个地方要还原为原本需要改变的点,不能直接变为'.')
        g[x][y] = tp[1];
        g[x + 1][y] = tp[2];
        g[x][y - 1] = tp[3];
        g[x][y + 1] = tp[4];
        if (x == 2 || x == n - 1 || y == 2 || y == m - 1) return ; // 如果当前是边界值,那么不需要再进行不涂,不然肯定存在涂不到的点
    }
    if (y + 1 < m) dfs(x,y + 1, ans , res);
    else dfs (x + 1,2, ans, res);
    return ;
}

int main(){
    int t;
    scanf("%d",&t);

    for (int k = 1; k <= t; k ++){
        mi = 2e9;
        scanf("%d%d",&n, &m);
        int res = 0;
        for (int i = 1; i <= n; i ++){
            for (int j = 1; j <= m; j++){
                cin>>g[i][j];
                if (g[i][j] == '#') res ++;
            }
        }

        dfs(2,2,0,res);

        if (g[1][1] == '#' || g[1][m] == '#' || g[n][1] == '#' || g[n][m] == '#' || mi == 2e9){
            printf("Image #%d: impossible\n",k);
            printf("\n");
            continue;
        }

         printf("Image #%d: %d\n",k,mi);
         printf("\n");
    }
    return 0;
}

你可能感兴趣的:(ICPC训练联盟)