码蹄集-竞赛真题第二期

第一题  小码哥配速问题

#include<bits/stdc++.h> 

using namespace std;
int num(char c){
    return c -'0';
}


int main( )
{
    char t[10];
    int x;
    int distance = 0,time=0;
    while(scanf("%d",&x)!=EOF){
        scanf("%s",t);
        time += (num(t[0]) * 10 +num(t[1])) * 60 + num(t[3])* 10 +num(t[4]);
        distance += x;
     }
     int ans  =time *1000 / distance;
     cout << ans /600 << ans / 60 % 10 << ":" << ans % 60 /10 << ans %10;
     
    return 0;
}

 其中关键的是,如何判断输入结束,在输入结束后,读取的末尾是EOF,只需要判断是否为EOF就可以知道是不是输入结束了!

while(scanf("%d",&x)!=EOF)

第二题 白日梦Ⅰ

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int n;
    cin >> n;
    double ans = 10;
    int mx = 0; //枚举最大汇率,美元换成英镑
    for (int i=1;i<=n;++i){
        int x;
        scanf("%d",&x);
        ans = max(ans,10.*(mx /10000.) * (10000. / x)); //英镑换成美元10000. / x
        mx = max(mx,x);//维护的是过去美元转英镑的最大汇率

    }
    printf("%.2lf\n",ans);
    return 0;

记录mx -美元换英镑的最大值,尽可能的多换成英镑,然后找到转换成美元的最大值,即找到x的最小值 。ans记录了之前转换成英镑的最大值后,每天都做一个转换成美元的计算,求出最大值。

第三题 双回文串

#include<bits/stdc++.h> 

using namespace std;

bool check(char str[], int l, int r){
    int mid = (l + r)/2;
    for (int i = l;i <= mid;i++)
        if(str[i] != str[l+r-i])
            return 0;
    return 1;
}

int main( )
{
    char str[1001];
    scanf("%s",str);
    int n = strlen(str);
    bool flag = false;
    for (int i =1;i<n;i++)
        if(check(str,0,i-1) && check(str,i,n-1))
            flag = true;
    if(flag)
        cout << "YES";
    else 
        cout << "NO";
    return 0;
}

第四题 甄别情报 

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int t;
    cin >> t;
    for (int i = 0;i <t;i++){
        int atoA[27] = {0},Atoa[27] = {0};
        char a[100],b[100];
        cin >> a >> b;
        int len = strlen(a);
        bool flag = true;
        for (int i=0;i<len;++i){
            int ida = a[i]-'a'+ 1,idb = b[i] - 'A' +1;
            if(atoA[ida]){
                if (atoA[ida] != idb){
                    flag = false;
                    break;
                    }
                } else
                    atoA[ida] = idb;
            if (Atoa[idb]){
                if(Atoa[idb] != ida){
                    flag = false;
                    break;}
                }
            else 
                Atoa[idb] = ida;
        }
        if(flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

Atoa和atoA两个列表 进行对照,判断是否为11对应的关系

第五题 数组稳定度

 先排序,试着删除最大值或者最小值,进行差值比较

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int n,a[100000];
    cin >> n;
    for (int i=0;i<n;i++)
        cin >> a[i];
    sort(a,a+n);
    int mx = a[n-1],mx2 = a[n-2];
    int mn = a[0],mn2 = a[1];
    int ans = min(mx-mn2,mx2-mn);
    cout << ans << endl;
    return 0;
}

第六题 MC0116 水往低处流

#include<bits/stdc++.h> 

using namespace std;
int a[2000][2000],n;
bool check(int i,int j){
    if(i >0 && a[i][j] < a[i-1][j]) return 0;
    if(j >0 && a[i][j] < a[i][j-1]) return 0;
    if(i < n - 1 && a[i][j] < a[i+1][j]) return 0;
    if(j < n-1 && a[i][j] < a[i][j+1]) return 0;
    return 1;
}
int main( )
{
    int ret = 0;
    cin >> n;
    for (int i = 0; i < n;i++)
        for (int j =0;j<n;j++)
            cin >> a[i][j];
    for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
            if(check(i,j))
                ret++;
    cout << ret;
    return 0;
}

check 寻找最高点,只要周围的四个点的高度都没有它高,那么就需要浇水了,标记为1 。那么标记为1 的有多少个,就需要浇水多少次。

第七题 MC0117 五行能量

#include<bits/stdc++.h> 
#define maxn 17
using namespace std;
int a[maxn][6],b[6]; //a 存储的五行石,b目标能量
int main(){ 
    int n;
    cin >> n;
    for (int i =1;i <= n;++i)
        cin >> a[i][1] >> a[i][2] >> a[i][3] >> a[i][4] >> a[i][5];
    cin >> b[1] >> b[2] >> b[3] >> b[4] >> b[5];
    for (int i =0;i<(1 << n); ++i){   //左移n位,相当于小于2的N次方  多少种方法1001=9
        int s[6] = {0}; //结果
        for (int k = 1;k <= n;++k) // 遍历最低位到最高位k=0
            if(i & (1 << (k-1))) //第k位是否为1
                for (int j =1;j<=5;++j) // 存储目标列的数值
                    s[j] += a[k][j];
        bool flag = true;
        for(int j = 1;j <= 5;++j)
            if(s[j] != b[j])
                flag = false;

        if(flag){
            for (int ii =1;ii<=n;ii++)
                if(i & (1 << (ii-1)))
                    cout << ii << " ";
            return 0;

        }
    }
}

 其思想是,遍历所有方法,将2^(n-1)种方法全部遍历一边,最后一行为目标值,s为某方法的结果值,最后两者进行每列的数值比较,如果相等则flag=true,不相等,就flag=false,就继续遍历。其中将是否要哪个五行石,看作0-1处理,并且根据先后顺序,来看作2的位数,从低位到高位,正好满足题目要求字典序最小的方案。

第八题 MC0118折纸

 

#include<bits/stdc++.h> 

using namespace std;
//每次反转,对应的边长就变为MAX(翻折过去的长度,原长度-翻折过去的长度)
int main( )
{
    double a,b;
    cin >> a >> b;
    int q;
    cin >> q;
    for (int i = 1; i <= q; ++i){
        char s;
        cin >> s;
        double xy;
        cin >> xy;
        if(s == 'L')
            a = max(xy, a-xy);
        else
            b = max(xy, b-xy);
    }
    printf("%.2lf %.2lf",a,b);
    return 0;
}

第九题 MC0119马走日

#include<bits/stdc++.h> 
#define maxn 1010
using namespace std;

int tx[8] = {1, 1, -1, -1, 2, -2, 2, -2};
int ty[8] = {2, -2, 2, -2, 1, 1, -1, -1};
struct NODE{
    int x, y;
};

int main( )
{
    queue<NODE> q;
    int dp[maxn][maxn];
    memset(dp, -1, sizeof(dp));
    int n;
    cin >> n;
    int a, b;
    cin >> a >> b;
    dp[a][b] = 0;
    q.push((NODE){a, b});
    // bfs算法
    while(!q.empty()){
        int x = q.front().x, y = q.front().y;
        q.pop();
        for(int i = 0;i < 8; ++i){
            int nx = x + tx[i],ny = y + ty[i];
            if(nx < 0 || nx > n || ny < 0 || ny > n)
                continue;
            if(dp[nx][ny] != -1)
                continue;
            dp[nx][ny] = dp[x][y] + 1;
            q.push((NODE){nx, ny});
        }
    }
    //dp数组上的值位最少到达的步数,如果是-1则无法到达
    int q2;
    cin >> q2;
    for (int i = 1; i <= q2; i++ ){
        int c,d;
        cin >> c >> d;
        cout << dp[c][d] <<endl;
    }    
    return 0;
}

 其中用到了BFS(宽度/广度优先搜索)系统性的展开,彻底的搜索整张图。其中dp数组就是全图遍历后的结果,图上是最少步数,如果是-1的话,就是无法到达了。

第十题 MC0120 码哥猜想

 

#include<bits/stdc++.h> 

using namespace std;

int main( )
{
    int ans;
    for(int i=1; i <= 100; ++i){
        int temp = i;
        bool flag = true;
        while(temp != 1){
            if(temp & 1)
                temp = temp * 5 - 1;
            else 
                temp = temp / 2;
            if(temp>1e7){
                flag = false;
                break;
            }
        }
        if(flag) cout << i << " ";
    }
    return 0;
}

在计算机中,数据以补码的二进制存储的。
偶数的最低位一定是0。
奇数的最低位一定是1。
所以如果要判断这个数是奇数还是偶数,只需要用这个数按位与1就可以了。
如果结果为0,那么这个数就是偶数,如果结果为1,那么这个数就是奇数。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值