2022寒假训练week4
Day1
今天除夕,比较懒
牛客2022年除夕AK场
很可惜没能ak
A 如意
利用PHP
直接水
1
B 烟花
一道很常见的模拟
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin >> n;
for( int i = 1 ; i <= n ; i ++ )
{
for( int j = 1 ; j < i ; j ++ ) cout << ' ';
cout << '\\';
for( int j = i + 1 ; j <= n ; j ++ ) cout << ' ';
cout << '|';
for( int j = i + 1 ; j <= n ; j ++ ) cout << ' ';
cout << '/';
for( int j = 1 ; j < i ; j ++ ) cout << ' ';
cout << endl;
}
for( int i = 1 ; i <= n ; i ++ ) cout << "-";
cout << "O";
for( int i = 1 ; i <= n ; i ++ ) cout << "-";
cout << endl;
for( int i = n ; i >= 1 ; i -- )
{
for( int j = 1 ; j < i ; j ++ ) cout << ' ';
cout << '/';
for( int j = i + 1 ; j <= n ; j ++ ) cout << ' ';
cout << '|';
for( int j = i + 1 ; j <= n ; j ++ ) cout << ' ';
cout << '\\';
for( int j = 1 ; j < i ; j ++ ) cout << ' ';
cout << endl;
}
return 0;
}
C 瑞雪
只要在完成的前一秒发射就好!
x,y,a = map( int , input().split(" ") )
print( (y * a - 1) // x )
D 红包
这里可以利用字符串的比较来做,首先先比较字符串的长度,才有可能是最长的。然后把字符串中的X
都换成9
然后再比较就好
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n , m , res , len;
string cur , maxstr;
inline int read()
{
int x = 0 , ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x;
}
int main()
{
n = read();
for( int i = 1 ; i <= n ; i ++ )
{
cin >> cur;
if( cur.size() < len ) continue;
else if ( cur.size() == len )
{
for( auto &it : cur )
if( it == 'X' ) it = '9';
if( cur > maxstr ) maxstr = cur , res = i;
}
else
{
for( auto &it : cur )
if( it == 'X' ) it = '9';
res = i , len = cur.size() , maxstr = cur;
}
}
cout << res << endl;
return 0;
}
E 春联
很可惜不会,尽管出题人已经说出了做法
ac自动机fail树上建可持久化线段树
后缀自动机next指针dag图上求sg函数
留一个坑明年来补
Day6
AtCoder Beginner Contest 238
A
判断\(2^n>n^2\)是否成立的,直接算会tle
,所以本地打个表就行了
n = int(input())
if( n == 2 or n == 3 or n == 4 ):
print("No")
else :
print("Yes")
B
有一个披萨,我们只能在十二点的地方进行切割每次课旋转一个度数,问最大的披萨有多少度
因为度数只有360,所以用一个数组记录哪个读书被切了,然后统计一下
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n , t , last , ans;
bool a[360];
int main()
{
a[0] = 1;
cin >> n;
for( int x , i = 1 ; i <= n ; i ++ )
{
cin >> x;
t = ( t + x ) % 360;
a[t] = 1;
}
for( int i = 0 ; i < 360 ; i ++ )
if( a[i] ) ans = max( ans , i - last ) , last = i;
ans = max( ans , 360 - last );
cout << ans << endl;
}
C
\(f(x)\)是指[1,x]
中与x
位数相同的数的个数,求\(\sum_{i=1}^n f(i)\)
首先对于相同位数的且相邻的数他们的值是等差数列,所以要按照位数先进性划分,然后每一位用求和公式即可,因为要取模这里求和公式中的除二要用逆元,逆元可以提前算好,但是不知道为什么我的在写的过程中long long
溢出了,所以用python
写的
import math
mod = 998244353
inv = 499122177
n = int(input())
m = int(math.log10(n))
res = 0
now = 10
last = 1
for i in range( 0 , m ):
len = ( now - last ) % mod
a = ( now + last - 1 ) % mod
b = ( last - 1 ) % mod
res += a * len % mod * inv % mod
res %= mod
res -= b * len % mod
res %= mod
res += mod
res %= mod
last = now
now *= 10
len = ( n - last + 1 ) % mod
a = ( n + last ) % mod
b = ( last - 1 ) % mod
res += a * len % mod * inv % mod
res %= mod
res -= b * len % mod
res %= mod
res += mod
res%=mod
print(res)
D
给定a,s
问是否有x,y
满足x&y==a && x+y==s
首先若相与后等于a
则x,y
最小值一定是a
,然后可以在任意非1
的位置加一个1
,把后加的一相加得到c
,则满足c=s-2*a
,然后c,a
一定不能有某一位都是1,两个数一与就行
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
ll t , a , s , c;
void slove()
{
cin >> a >> s;
c = s - 2*a;
if( c < 0 )
{
cout << "No\n";
return ;
}
if( a & c ) cout << "No\n";
else cout << "Yes\n";
}
int main()
{
cin >> t;
while( t -- ) slove();
}
Day7
AcWing 第37场周赛
A 合适数对
数据很小,直接枚举就好
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n , a , b , x , y , f ;
int main()
{
cin >> n >> a >> b;
for( x = 0 ; a * x <= n && !f ; x ++ )
{
for( y = 0 ; a * x + y * b <= n && !f ; y ++ )
if( a*x + y*b == n ) printf("YES\n%d %d\n" , x , y ) , exit(0);
}
printf("NO\n");
return 0;
}
B 截断的数组
枚举前缀,二分后缀
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 2e5+5;
int a[N] , n;
ll b[N] , res , sum;
inline int read()
{
int x = 0 , ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x;
}
int main()
{
n = read();
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
for( int i = n ; i >= 1 ; i -- ) b[i] = b[i+1] + a[i];
for( int i = 1 , t ; i <= n ; i ++ )
{
sum += a[i];
t = lower_bound( b+1+i , b+1+n , sum , greater<ll>() )-b;
if( t > i && b[t] == sum ) res = sum;
}
cout << res << endl;
return 0;
}
C 搭档
可以用匈牙利算法或者是网络流,这里用贪心来做,就是把男女都排个序然后双指针扫一遍
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 105;
int n , m , a[N] , b[N] , res ;
inline int read()
{
int x = 0 , ch = getchar();
while( ch < '0' || ch > '9' ) ch = getchar();
while( ch >= '0' && ch <= '9' ) x = ( x << 3 ) + ( x << 1 ) + ch - '0' , ch = getchar();
return x;
}
int main()
{
n = read();
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
m = read();
for( int i = 1 ; i <= m ; i ++ ) b[i] = read();
sort( a + 1 , a + 1 + n ) , sort( b + 1 , b + 1 + m );
for( int i = 1 , j = 1 ; i <= n ; i ++ )
{
while( j <= m && a[i] > b[j] + 1 ) j ++;
if( j <= m && a[i] >= b[j] - 1 ) res ++ , j ++;
}
cout << res << endl;
return 0;
}