2020ICPC上海站补题题解

这场4题铜,5~6题银

M Gitignore

去年比赛的时候还没用过git,被题意整懵了硬是看了巨久。然后场上的思路是模拟,结果码力太差没写出来,tcl。

题意:gitignore,上传文件,n个路径是要删的,m个路径是不能删的,问最小删几个文件。

思路

对于m个不能删的,把他所有的父目录都标注为1保护起来。

然后再去遍历n个要删的,令ans=n,如果目录vis为0,说明没有被保护,并第一次出现,标注为2,碰到标注为2的,说明没被保护,且前面出现过,就可以合并,那么ans-1

代码

#include<bits/stdc++.h>
#include<iostream>
#include <stdio.h>
using namespace std;
const int maxn=2005;
const int base=131;
typedef long long ll;
#define pi acos(-1)
#define INF 0x3f3f3f3f
#define mod 998244353
const int inf=1<<30;
vector<int> g[maxn];
vector<string> str1,str2;
map<string,int> vis;
int main()
{
    
    
    //freopen("data.in","r",stdin);
    //freopen("1.out","w",stdout);
     ios::sync_with_stdio(false); cin.tie(0);
    int t,n,m;
    cin>>t;
    while(t--){
    
    
        cin>>n>>m;
        string s;
        vis.clear();
        str1.clear();
        str2.clear();
        for(int i = 0; i< n;i++){
    
    
            cin>>s;
            str1.push_back(s);
        }
        for(int i = 0; i< m;i++){
    
    
            cin>>s;
            str2.push_back(s);
            string ss="";
            for(int j = 0; j < s.size(); j++){
    
    
                ss += s[j];
                if(s[j] == '/'||j == s.size() - 1){
    
    
                    vis[ss] = 1;
                   // cout<<ss<<endl;
                }
            }
        }
        int ans = n;
        for(int i = 0;i < n; i++){
    
    
            string ss = "";
            for(int j = 0;j < str1[i].size(); j++){
    
    
                ss += str1[i][j];
                if(str1[i][j] == '/'||j == str1[i].size() - 1){
    
    
                    //cout<<ss<<endl;
                    if(vis[ss] == 2){
    
    
                        ans--;
                        break;
                    }
                    if(vis[ss] == 0)
                        vis[ss] = 2;

                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

B Mine Sweeper II

思路

思维题,看B能否在 [ n m 2 ] [\frac{nm}{2}] [2nm]步内变为A或A的相反矩阵(也就是X变成 . . . . . .变成X)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
string s1[1005],s2[1005];
int main()
{
    
    
    std::ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=0;i<n;i++) 
        cin>>s1[i];
    for(int i=0;i<n;i++) 
        cin>>s2[i];  
    int cnt1,cnt2;
    cnt1 =cnt2=0;
    for(int i=0;i<n;i++)
    {
    
    
        for(int j=0;j<m;j++)
        {
    
    
            if(s2[i][j]!=s1[i][j]) cnt1++;
            if(s2[i][j]==s1[i][j])
                cnt2++;
        }
    }
    if(cnt1<=(m*n)/2) {
    
    
        for(int i = 0;i<n;i++)
            cout<<s1[i]<<endl;
    }
    else if(cnt2<=(m*n)/2){
    
    
        for(int i = 0;i<n;i++){
    
    
            for(int j = 0 ;j < m;j++){
    
    
                if(s1[i][j] == 'X')
                    cout<<".";
                else
                    cout<<"X";
            }
            cout<<endl;       
        }
    }
    else
    {
    
    
        cout<<-1<<endl;
    }
    system("pause");
    return 0;
}

D Walker

题意

给定一段路的距离,两个人的初始位置,速度,问最小需要多少时间走完全部路程。

思路

分三种情况讨论,第一种一个人跑完全部,取两个人都跑完的较小情况。

第二种两个人对着走,也就是第一个人走p1到n,第二个人走0到p2。

第三种两个人都到中间任意一点,再反转回各自的方向,取两个人走完的最大值。对于这个点的具体位置可以二分求解。

代码

#include<bits/stdc++.h>
using namespace std;
double n,p1,v1,p2,v2,p3;
double ans;

double cal(double x,double p,double v){
    
    
    return min(x + p,x + x - p) / v;
}
double slove(double l,double r)
{
    
    
    for(int i = 0; i < 100 ; i++){
    
    
        double m = (l + r) / 2.0;
        double ll = cal(m,p1,v1);
        double rr = cal(n - m,p2 - m,v2);
        ans = min(ans,max(ll,rr));
        if(ll < rr)
            l = m;
        else
            r = m;
    }
    return ans;
}

int main()
{
    
    
    std::ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
    
    
        cin>>n>>p1>>v1>>p2>>v2;
        if(p1 > p2){
    
    
            swap(p1,p2);
            swap(v1,v2);
        }
        double t1 = min(cal(n,p1,v1),cal(n,p2,v2));
        double t2 = max((n - p1) / v1,p2 / v2);
        ans = min(t1,t2);
        double t3 = slove(p1,p2);
        printf("%.10lf\n",ans);
    }
    return 0;
}

I Sky Garden

代码

#include<bits/stdc++.h>
#include<iostream>
#include <stdio.h>
using namespace std;
const int maxn=2005;
const int base=131;
typedef long long ll;
#define pi acos(-1)
#define INF 0x3f3f3f3f
#define mod 998244353
const double PI = acos(-1);
const int inf = 1<<30;
double a[maxn],b[maxn];

int main()
{
    
    
    //freopen("data.in","r",stdin);
    //freopen("1.out","w",stdout);
     ios::sync_with_stdio(false); cin.tie(0);
    int n,m;
    cin>>n>>m;
    double cnt = 0.0;
    for(int i = 1; i < 2 * m;i++){
    
    
        cnt += min(2.0, PI * min(i*1.0,2.0 * m - i) / m);
    }
    a[1] = b[1] = cnt;
    for(int i = 2;i <= n;i++){
    
    
        b[i] = i * 1.0 * b[1];
        a[i] = a[i - 1] + b[i] + 2.0 * m * (i - 1);
    }
    double ans = 0.0;
    for(int i =1 ;i <= n;i++){
    
    
        ans += (a[i] - b[i]) * 2.0 * m + b[i] * 2.0 * m / 2.0;
        if(m > 1)
            ans += 2.0 * m * i; 
    }
    printf("%.10lf\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/u011612364/article/details/115006297