7/31 训练日志

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7/31 训练日志相关的知识,希望对你有一定的参考价值。

每日一题 C. Zero Path

明白了结论,这题就不难了,思路:
1.n+m为偶数时,经过的格子数为n+m-1,不可能得到累加得到0
2.设计状态,这个较为简单。mx[i][j]表示到达i行j列时可得答案最大值,mi[i][j]表示到达i行j列时可得答案最小值。
3.若0在最小和最大值之间,则说明有一条路径使得累加结果为0.

#include <bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;
const int N = 1e5+100;
const int mod=998244353;
int n,m,a[1005][1005],mi[1005][1005],mx[1005][1005];

signed main()

    int t;cin>>t;
    while(t--)
    
        cin>>n>>m;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=m;j++)
            mi[i][j]=1e18,mx[i][j]=-1e18;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            cin>>a[i][j];
        mi[1][1]=mx[1][1]=a[1][1];
        if((n+m)%2==0)
        
            cout<<"NO"<<endl;continue;
        
        for(int i=1;i<=n;i++)
        
            for(int j=1;j<=m;j++)
            
                mi[i][j]=min(mi[i][j],mi[i-1][j]+a[i][j],mi[i][j-1]+a[i][j]);
                mx[i][j]=max(mx[i][j],mx[i-1][j]+a[i][j],mx[i][j-1]+a[i][j]);
            
        
        //cout<<mi[n][m]<<"------"<<mx[n][m]<<endl;
        if(mi[n][m]>0||mx[n][m]<0)
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    

    return 0;


__int128的读入写出大概10^38范围,用于处理大数,但它能不能使用取决于编译器,大部分OJ是支持的

__int128 read()

    __int128 f=1,w=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    
        if(ch=='-')
        f=-1;
        ch=getchar();
    
    while(ch<='9'&&ch>='0')
    
        w=w*10+ch-'0';
        ch=getchar();
    
    return f*w;

void print(__int128 x)

    if(x<0)
    
        putchar('-');
        x=-x;
    
    if(x>9)print(x/10);
    putchar(x%10+'0');

"蔚来杯"4 Jobs (Easy Version)

思路:
1.此类题好久没做了,应注意到iq,eq,aq的值在1 ~400的范围内,公司数在1 ~10范围内。
2.采用dp的方式记录第k家公司iq为i,eq为j时,对aq的最低要求是多少

#include <bits/stdc++.h>
#include <random>
#define int long long
using namespace std;

const int N = 1e5+100;
const int mod=998244353;
int seed,lastans;
int n,q,f[15][405][405];

int fastpow(int a,int b)

    int res=1;
    while(b)
    
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    
    return res;


int solve(int x,int y,int z)

    int res=0;
    for(int i=1;i<=n;i++)
        if(z>=f[i][x][y])
        res++;
    return res;


signed main()

    cin>>n>>q;
    for(int k=0;k<=10;k++)
    for(int i=0;i<=400;i++)
        for(int j=0;j<=400;j++)
            f[k][i][j]=1e9;
    for(int i=1;i<=n;i++)
    
        int k;cin>>k;
        for(int j=1;j<=k;j++)
        
            int x,y,z;cin>>x>>y>>z;
            f[i][x][y]=min(f[i][x][y],z);
        
    
    cin>>seed;
    for(int k=1;k<=n;k++)
        for(int i=1;i<=400;i++)
        for(int j=1;j<=400;j++)
    f[k][i][j]=min(f[k][i][j],f[k][i-1][j],f[k][i][j-1]);
    std::mt19937 rng(seed);
    std::uniform_int_distribution<> u(1,400);
    int ans=0;
    for (int i=1;i<=q;i++)
    
        int IQ=(u(rng)^lastans)%400+1;  // The IQ of the i-th friend
        int EQ=(u(rng)^lastans)%400+1;  // The EQ of the i-th friend
        int AQ=(u(rng)^lastans)%400+1;  // The AQ of the i-th friend
        lastans=solve(IQ,EQ,AQ);  // The answer to the i-th friend
        ans=(ans+lastans*fastpow(seed,q-i)%mod)%mod;
    
    cout<<ans<<endl;
    return 0;


"蔚来杯"4 Particle Arts

思路:
1.想到了会二进制中“1”两极分化,且不会无故消失。需要统计各个数位上1的个数
2.没想到需要在原数组基础上构建一个新的数组,思维太差了。。。

#include<bits/stdc++.h>
#define int __int128
#define endl '\\n'
//#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)

using namespace std;
const int N=1e5+5;
const int mod=1e9+7;
int n,a[N],b[N],c[N];
__int128 read()

    __int128 f=1,w=0;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    
        if(ch=='-')
        f=-1;
        ch=getchar();
    
    while(ch<='9'&&ch>='0')
    
        w=w*10+ch-'0';
        ch=getchar();
    
    return f*w;

void print(__int128 x)

    if(x<0)
    
        putchar('-');
        x=-x;
    
    if(x>9)print(x/10);
    putchar(x%10+'0');

signed main()

    //IOS;
    n=read();
    int sum=0;
    for(int i=1;i<=n;i++)
        a[i]=read(),sum+=a[i];
    for(int i=1;i<=n;i++)
    
        for(int j=0;j<=15;j++)
        
            if((a[i]>>j)&1==1)
                b[j]++;
        
    
    for(int i=1;i<=n;i++)
    
        for(int j=15;j>=0;j--)
        
            if(b[j])
                c[i]+=1<<j,b[j]--;
        
    
    int ans=0;
    for(int i=1;i<=n;i++)
        ans+=(n*c[i]-sum)*(n*c[i]-sum);
    int k=n*n*n;
    int g=__gcd(ans,k);
    print(ans/g);
    printf("/");
    print(k/g);
    printf("\\n");
    return 0;


"蔚来杯"4 NIO’s Sword

题意:武器开始攻击力为A(初始为0),通过公式10*A+x对n进行取模等于i则杀死第i个人,最少进行几次变换
思路:
1.任何数模1答案都为0
2.

#include <bits/stdc++.h>
#define int long long
#define endl '\\n'
using namespace std;
const int N = 1e5+100;
const int mod=998244353;
int n,f[15];
int cal(int n)

    int res=0;
    for(int i=1;i<=n;i++)
    
        int g=i-1;
        for(int j=0;j<=15;j++)
        
            int k=g*f[j];
            k=((i-k)%n+n)%n;
            if(k<f[j])
            
                res+=j;break;
            
        
    
    return res;

signed main()

    f[0]=1;
    for(int i=1;i<=15;i++)
        f[i]=f[i-1]*10;
    cin>>n;
    cout<<cal(n)<<endl;

    return 0;


以上是关于7/31 训练日志的主要内容,如果未能解决你的问题,请参考以下文章

天梯赛 训练round 3

「国庆训练」Bomb(HDU-5934)

如何确保预测时间图像输入与训练时间图像输入在同一范围内?

ACM2022.7.31训练赛

第一次训练题解

8/2 训练日志(dp+思维+字典树)