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 训练日志的主要内容,如果未能解决你的问题,请参考以下文章