牛客小白月赛56
A 阿宁的柠檬
签到
#include<bits/stdc++.h>
#define int long long
using namespace std;
int32_t main() {
int a , b , n;
cin >> a >> b >> n;
cout << n << " " << ( a + b ) * n << "\n";
return 0;
}
B 阿宁与猫咪
最优的分发肯定是分成m
个 1 ,这道题总感觉题面不是很通顺
#include<bits/stdc++.h>
#define int long long
using namespace std;
int32_t main() {
int a;
cin >> a;
cout << a << "\n";
for( int i = 1 ; i <= a ; i ++ )
cout << "1 ";
return 0;
}
C 阿宁吃粽子
首先容易知道的是,大的乘大的结果更优。
然后我们把整个队列分层若干组,第一组有 9 个,中间组有 10 个,最后一组有n%10
个
然后把所有人拍个序,依次分散到每个组里就好了。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n , a[N] , m , k, c[N];
vector<int> res[N];
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
n = read() , m = n / 10 + 1 , k = n % 10 ;
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
sort( a + 1 , a + 1 + n );
if( n < 10 ){
for( int i = 1 ; i <= n ; i ++ )
cout << a[i] << " ";
exit(0);
}
int id = 1;
for( int i = 1 ; id <= n ; i = ( i + 1 ) % m ){
if( i == m-1 && res[i].size() == k+1 ) continue;
res[i].push_back( a[id++] );
}
for( int i = 0 ; i < m ; i ++ )
for( auto it : res[i] )
cout << it << " ";
}
D 阿宁的质数
把前n+1
个质数全部找出来,然后放到一个 set 里面,对于序列 a,把前 i 位里的质数从 set 中删掉,然后输出最小的就是答案。可以自己枚举所有可能的情况然后静态回答就好了。
然后就是估计质数的个数用\(\frac{x}{\ln(x)}\)就好
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n , a[N] , m , k, c[N];
vector<int> res[N];
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
n = read() , m = n / 10 + 1 , k = n % 10 ;
for( int i = 1 ; i <= n ; i ++ ) a[i] = read();
sort( a + 1 , a + 1 + n );
if( n < 10 ){
for( int i = 1 ; i <= n ; i ++ )
cout << a[i] << " ";
exit(0);
}
int id = 1;
for( int i = 1 ; id <= n ; i = ( i + 1 ) % m ){
if( i == m-1 && res[i].size() == k+1 ) continue;
res[i].push_back( a[id++] );
}
for( int i = 0 ; i < m ; i ++ )
for( auto it : res[i] )
cout << it << " ";
return 0;
}
E 阿宁睡大觉
相邻的两个Z
贡献是 4。先扫一遍字符串,统计所有的相邻的Z
,同时统计不相邻的Z
的间距,然后从小到大的删除
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n , m , res;
vector<int> v , q ;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int32_t main() {
n = read() , m = read();
string s;
cin >> s;
for( int i = 0 ; i < n ; i ++ )
if( s[i] == 'Z' ) v.push_back(i);
for( int i = 1 ; i < v.size() ; i ++ )
if( v[i] - v[i-1] == 1 ) res += 4;
else q.push_back( v[i] - v[i-1] - 1 );
sort( q.begin() , q.end() );
for( auto it : q ){
if( it > m ) break;
m -= it , res += 4;
}
cout << res << "\n";
}
F 阿宁去游玩
把其他所有的点异或1,等价于把当前点异或。考虑用 dij 求最短路,因为 dikstraj 不会走回头路,所以异或当前点产生的影响只会影响与当前点所连的边,这样的话如果两点相同边权就是min( x , y + z )
,两点不同就是min(y , x + z )
建好图跑一遍 dijkstra
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+5;
int n , m , dis[N] , valX , valY , valZ;
vector<pair<int,int>> e[N];
bitset<N> state , vis;
int read() {
int x = 0, f = 1, ch = getchar();
while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
if (ch == '-') f = -1, ch = getchar();
while (ch >= '0' && ch <= '9') x = (x << 3) + (x << 1) + ch - '0', ch = getchar();
return x * f;
}
int D( int x , int y ){
if( state[x] == state[y] ) return valX;
return valY;
}
void dij(){
fill( dis , dis + N , LLONG_MAX );
dis[1] = 0;
priority_queue< pair< int , int > , vector<pair< int , int >> , greater<pair< int , int >> > q;
q.push( { 0 , 1 } );
while( !q.empty() ){
int u = q.top().second ; q.pop();
if( vis[u] ) continue;
vis[u] = 1;
for( auto [ v , w ] : e[u] ){
if( vis[v] || dis[v] <= dis[u]+w ) continue;
dis[v] = dis[u] + w;
q.push( { dis[v] , v } );
}
}
}
int32_t main() {
n = read() , m = read();
valX = read() , valY = read() , valZ = read();
valX = min( valX , valY+valZ ) , valY = min( valY , valX + valZ );
for( int i = 1 , x ; i <= n ; i ++ )
state[i] = read();
for( int u , v ; m ; m -- ){
u = read() , v = read();
e[u].push_back( { v , D(u,v) } ) , e[v].push_back( { u , D(u,v) } );
}
dij();
cout << dis[n] << "\n";
}