《中国计量大学现代科技学院第四届“中竞杯”程序设计校赛部分题解》

A:签到

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 5e4+5;
const int M = 1e2+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

string s[5];
bool vis[5][5];
int C(int n,int m)
{
    if(n == m || m == 0) return 1;
    else return C(n - 1,m - 1) + C(n - 1,m);
}
int main()
{
    for(int i = 0;i < 3;++i) cin >> s[i];
    int num = 0;
    for(int i = 0;i < 3;++i)
    {
        for(int j = 0;j < 3;++j) if(s[i][j] == 'X') vis[i][j] = 1,num++;
    }
    int ma = 0;
    if(s[0][0] != 'X' && s[0][1] != 'X' && s[0][2] != 'X') ma++;
    if(s[1][0] != 'X' && s[1][1] != 'X' && s[1][2] != 'X') ma++;
    if(s[2][0] != 'X' && s[2][1] != 'X' && s[2][2] != 'X') ma++;

    if(s[0][0] != 'X' && s[1][0] != 'X' && s[2][0] != 'X') ma++;
    if(s[0][1] != 'X' && s[1][1] != 'X' && s[2][1] != 'X') ma++;
    if(s[0][2] != 'X' && s[1][2] != 'X' && s[2][2] != 'X') ma++;

    if(s[0][0] != 'X' && s[1][1] != 'X' && s[2][2] != 'X') ma++;
    if(s[0][2] != 'X' && s[1][1] != 'X' && s[2][0] != 'X') ma++;
    num = 9 - num;
    int tmp = C(num,3);
    if(ma == 0) printf("0\n");
    else
    {
        int gcd = __gcd(tmp,ma);
        tmp /= gcd,ma /= gcd;
        printf("%d %d\n",ma,tmp);
    }
  //  system("pause");
    return 0;
}
View Code

H:签到

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 5e4+5;
const int M = 1e2+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int num = 0;
        while(n > 1)
        {
            if(n % 2 != 0) n--;
            else n /= 2;
            num++;
        }
        printf("%d\n",num);
    }
   // system("pause");
    return 0;
}
View Code

B:签到

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 1e4+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int a[N],tot = 0,sz[N];
int main()
{
    int n;n = read();
    string s;cin >> s;
    for(int i = 0;i < s.size();++i)
    {
        if(i == 0) 
        {
            a[++tot] = s[i] - 'A';
            sz[tot] = 1;
        }
        else 
        {
            if(s[i] == s[i - 1])
            {
                sz[tot]++;
            }
            else
            {
                a[++tot] = s[i] - 'A';
                sz[tot] = 1;
            }
            
        }   
    }
    int ans = 0;
    for(int i = 1;i <= tot;++i)
    {
        if(i == tot)
        {
            ans = max(ans,sz[tot]);
        }
        else
        {
            if(a[i] == 0)
            {
                ans = max(ans,sz[i] + sz[i + 1]);
            }
            else
            {
                int ma = sz[i - 1] + sz[i] + sz[i + 1] + sz[i + 2];
                ans = max(ma,ans);
            }
            
        }
    }
    printf("%d\n",ans);
  //  system("pause");
    return 0;
}
View Code

D:签到

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 5e4+5;
const int M = 1e2+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int main()
{
    string s;cin >> s;
    string t;cin >> t;
    map<char,int> mp;
    for(auto v : s) mp[v]++;
    int f = 0;
    for(auto v : t) if(mp[v] != 0) f = 1;
    printf("%s\n",f ? "yes" : "no");
    //system("pause");
    return 0;
}
View Code

C:我们贪心地考虑,如果以某个点为终点开始变形。

那么显然是要和最前面的一段满足的来变形,这样得到的代价一定是最优的。

枚举一下终点即可。这个起点可以用前缀和来找。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 2e5 + 5;
const int M = 1e4+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int a[N],tot = 0,sz[N],sum[N],mi[N],nxt[N][2],pre[N][2];// 0 - A,1 - B
int aa[N],bb[N],tot1 = 0,tot2 = 0;
int main()
{
    int n;n = read();
    string s;cin >> s;
    for(int i = 0;i < s.size();++i)
    {
        if(s[i] == 'A') a[i + 1] = -1;
        else a[i + 1] = 1;
    }
    for(int i = 1;i <= n;++i) 
    {
        sum[i] = sum[i - 1] + a[i];
        if(mi[sum[i]] == 0) mi[sum[i]] = i;
        if(a[i] == -1) aa[++tot1] = i;
        else bb[++tot2] = i;
    }
    int nowa = 0,nowb = 0;
    for(int i = 1;i <= n;++i)
    {
        int pos1 = upper_bound(aa + 1,aa + tot1 + 1,i) - aa;
        if(pos1 > tot1) nxt[i][0] = 0;
        else nxt[i][0] = aa[pos1];
        int pos2 = upper_bound(bb + 1,bb + tot2 + 1,i) - bb;
        if(pos2 > tot2) nxt[i][1] = 0;
        else nxt[i][1] = bb[pos2];
        pre[i][0] = nowa,pre[i][1] = nowb;
        if(a[i] == -1) nowa = i;
        else nowb = i;
     //   printf("nxt[%d][0] is %d nxt[%d][1] is %d\n",i,nxt[i][0],i,nxt[i][1]);
     //   printf("pre[%d][0] is %d pre[%d][1] is %d\n",i,pre[i][0],i,pre[i][1]);
    }
    int ans = 0;
    for(int i = 1;i <= n;++i)
    {
        if(a[i] == -1) 
        {
            int np = nxt[i][1];
            if(np == 0) np = n + 1;
            else np = nxt[np][0];
            if(np == 0) np = n + 1;
            ans = max(ans,np - i);
        }
        else 
        {
            int np = nxt[i][0];
            if(np == 0) np = n + 1;
            ans = max(ans,np - i);
        }
        if(mi[sum[i]] != 0 && mi[sum[i]] != i)
        {
            int len = i - mi[sum[i]];
           // printf("part1 len is %d\n",len);
            int np = nxt[i][0];
            if(np == 0) np = n + 1;
            len += np - i - 1;
          //  printf("over1 len is %d\n",len);
            len += mi[sum[i]] - pre[mi[sum[i]] + 1][1];
           // printf("over2 len is %d\n",len);
            ans = max(ans,len);
        }
        if(sum[i] == 0)
        {
           // printf("part2\n");
            int len = i;
            int np = nxt[i][0];
            if(np == 0) np = n + 1;
            len += np - i - 1;
            ans = max(ans,len);
        }
      //  dbg(ans);
    }
    printf("%d\n",ans);
    //system("pause");
    return 0;
}

//6 BBABAB
View Code

F:先对每一层背包。(三种情况)

然后就可以对全部层背包了,为了维护复杂度每层算到size个就够了。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 105;
const int M = 1e4+5;
const LL Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e18
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline LL read(){
        LL x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
        return x*f;
    }
}
using namespace FASTIO;

int n,m,sz[N],w[N][M],dp[N][M],bs[N][N],pre[N][N];
int main()
{
    n = read(),m = read();
    for(int i = 1;i <= n;++i)
    {
        sz[i] = read();
        for(int j = 1;j <= sz[i];++j) w[i][j] = read();
        for(int j = 1;j <= sz[i];++j) pre[i][j] = pre[i][j - 1] + w[i][j];
    }
    for(int i = 0;i <= n;++i)
        for(int j = 1;j <= m;++j) dp[i][j] = -1;
    for(int i = 1;i <= n;++i)
    {
        for(int j = 1;j <= sz[i];++j)
        {
            bs[i][j] = max(pre[i][j],pre[i][sz[i]] - pre[i][sz[i] - j]);
            for(int k = 1;k <= sz[i];++k)
            {
                if(k >= j) break;
                int ss = (j - k);
                bs[i][j] = max(bs[i][j],pre[i][k] + pre[i][sz[i]] - pre[i][sz[i] - ss]);
            }
        }
    }
    for(int i = 1;i <= n;++i)
    {
        for(int k = 1;k <= m;++k)
        {
            for(int j = 1;j <= sz[i];++j)
            {
                if(k >= j && dp[i - 1][k - j] != -1) 
                {
                    //printf("dp[%d][%d] is %d dp[%d][%d] is %d bs[%d][%d] is %d\n",i,k,dp[i][k],i - 1,k - j,dp[i - 1][k - j],i,j,bs[i][j]);
                    dp[i][k] = max(dp[i][k],max(dp[i - 1][k],dp[i - 1][k - j] + bs[i][j]));

                }
            }
        }
    }
    printf("%d\n",dp[n][m]);
   // system("pause");
    return 0;
}
/*
3 4
3 2 9 4
3 3 7 2
3 1 8 1

*/
View Code

I:考虑四向bfs,dp松弛。

显然这样会TLE。可以发现这里是个我们要让长的路尽可能在满足的情况内。

所以我们直接bfs中动态维护答案,并且剪枝去过大的情况,这样的bfs复杂度应该是在总点数5000 * 5000左右。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
const int N = 5e3+5;
const int M = 1e3+5;
const LL Mod = 1e9 + 7;
#define pi acos(-1)
#define INF 1e9
#define CT0 cin.tie(0),cout.tie(0)
#define IO ios::sync_with_stdio(false)
#define dbg(ax) cout << "now this num is " << ax << endl;
namespace FASTIO{
    inline int read(){
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9'){if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9'){x = (x << 1) + (x << 3) + (c ^ 48);c = getchar();}
        return x * f;
    }
}
using namespace FASTIO;

int n,m,sx,sy,ex,ey,dp[5005][5005][4],b[4][2] = {1,0,-1,0,0,1,0,-1},ans = INF;
string a[5005];
struct Node{int x,y,step,fx;};
void bfs()
{
    queue<Node> Q;
    for(int i = 0;i < 4;++i)
    {
        dp[sx][sy][i] = 0;
        Q.push(Node{sx,sy,0,i});
    }
    while(!Q.empty())
    {
        Node q = Q.front();
        Q.pop();
        if(q.step >= ans) continue;
        for(int i = 0;i < 4;++i)
        {
            int px = q.x + b[i][0];
            int py = q.y + b[i][1];
            int ma = q.step;
            if(i != q.fx) ma++;
            if(ma >= ans) continue;
            if(px >= 0 && px < n && py >= 0 && py < m && a[px][py] == '0' && ma < dp[px][py][i])
            {
                dp[px][py][i] = ma;
                Q.push(Node{px,py,ma,i});
                if(px == ex && py == ey) ans = min(ans,ma);
            }
        }
    }
}
int main()
{
    n = read(),m = read(),sx = read(),sy = read(),ex = read(),ey = read();
    for(int i = 0;i < n;++i) cin >> a[i];
    for(int i = 0;i < n;++i)
        for(int j = 0;j < m;++j) 
            for(int k = 0;k < 4;++k) dp[i][j][k] = INF;
    bfs();
    printf("%d\n",ans == INF ? -1 : ans);
    //system("pause");
    return 0;
}
View Code

E:比赛的时候考虑了一下狄利克雷卷积,写了一会没卷出来就撤了。

看了下大佬们的代码,这里有个结论就是k >= 27这个值就是0。

至于怎么得出的我还没想出来。。

知道了这个结论之后就很简单了,递归求解。

对于里面的那层分块 + 记忆化一下然后就可以很快求出了。

代码咕

posted @ 2020-12-06 09:50  levill  阅读(144)  评论(0编辑  收藏  举报