A
思路:找出最简单的2个长度的情况就行。
Code:
#include <bits/stdc++.h>
using namespace std;
int main(){
string s ;
int n ;
cin >> n ;
cin >> s ;
for( int i = 0 ; i < n - 1 ; i++ ){
if( s[i] != s[i+1] ){
cout << "YES" << endl;
cout << s[i] << s[i+1] << endl ;
return 0 ;
}
}
cout << "NO" << endl;
return 0 ;
}
B
思路:跟着模拟就行了。
Code:
#include <bits/stdc++.h>
using namespace std;
const int AX = 2e5 + 66 ;
int a[AX] ;
int b[AX] ;
int vis[AX] ;
int main(){
int n ;
cin >> n ;
for( int i = 0 ; i < n ; i++ ){
cin >> a[i] ;
}
for( int i = 0 ; i < n ; i++ ){
cin >> b[i] ;
}
int tot = 0 ;
int cnt = 0 ;
for( int i = 0 ; i < n ; i++ ){
if( vis[b[tot]] ){
cout << 0 << ' ' ; tot ++ ; i--; continue ;
}
vis[a[i]] = 1;
if( b[tot] != a[i] ){
cnt ++ ;
}else{
cout << cnt + 1 << ' ' ;
cnt = 0 ;
tot ++ ;
}
}
if( cnt ){
cout << cnt << ' ' ;
tot ++ ;
cnt = 0 ;
}
if( tot < n ){
for( int i = tot ; i < n ; i++ ){
cout << 0 << ' ' ;
}
}
cout << endl;
return 0 ;
}
C
题意:给出一串操作,从(0,0)走到x,y,问修改最小的区间长度(修改首尾距离),使得能走到(ex,ey)。
思路:二分区间长度,然后尺取法判断小于等于这个区间的修改是否能够满足,这部分我是这样处理的:先取消尺取过程范围内的操作,因为区间内可以随意修改,然后判断区间长度len能否满足从x,y最小步数走到ex,ey,并且剩余长度为偶数(抵消)。
Code:
#include <bits/stdc++.h>
using namespace std ;
const int AX = 2e5 + 66 ;
char s[AX] ;
int ex , ey ;
int n ;
int x , y ;
int cal( int x , int y ){
if( ( x <= 0 && y <= 0 ) || ( x >= 0 && y >= 0 ) ) return abs(abs(x)-abs(y)) ;
if( x < 0 && y > 0 ) return abs(x) + y ;
if( x > 0 && y < 0 ) return abs(y) + x ;
}
bool solve( int mid ){
int st = 0 , e = 0 ;
int n_x = x , n_y = y ;
int len = 0 ;
while( st <= e ){
while( e < n && len < mid ){
if( s[e] == 'U' ) n_y -- ;
if( s[e] == 'D' ) n_y ++ ;
if( s[e] == 'L' ) n_x ++ ;
if( s[e] == 'R' ) n_x -- ;
len ++ ;
int d_x = cal( ex , n_x ) ;
int d_y = cal( ey , n_y ) ;
if( len >= d_x + d_y && ( len - d_x - d_y ) % 2 == 0 ) return true ;
e ++ ;
}
if( s[st] == 'U' ) n_y ++ ;
if( s[st] == 'D' ) n_y -- ;
if( s[st] == 'L' ) n_x -- ;
if( s[st] == 'R' ) n_x ++ ;
st ++ ;
len -- ;
}
return false ;
}
int main(){
scanf("%d%s",&n,s) ;
scanf("%d%d",&ex,&ey) ;
if( n < abs(ex) + abs(ey) ){
return 0*printf("-1\n");
}else{
x = 0 , y = 0 ;
for( int i = 0 ; i < n ; i ++ ) {
if( s[i] == 'U' ) y ++ ;
if( s[i] == 'D' ) y -- ;
if( s[i] == 'L' ) x -- ;
if( s[i] == 'R' ) x ++ ;
}
if( x == ex && y == ey ) return 0*printf("0\n");
int l = 0 , r = n ;
int res = n + 1 ;
while( l <= r ){
int mid = ( l + r ) >> 1 ;
if( solve(mid) ){
res = mid ;
r = mid - 1 ;
}else{
l = mid + 1 ;
}
}
if( res == n + 1 ) printf("-1\n");
else printf("%d\n",res);
}
return 0 ;
}
D
思路:暴力,
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std ;
const int AX = 2e5 + 666 ;
int a[AX] ;
int vis[AX] ;
int main(){
int n ;
LL T ;
cin >> n >> T ;
LL sum = 0LL ;
for( int i = 0 ; i < n ; i++ ){
cin >> a[i] ;
sum += a[i] ;
}
LL res = 0LL ;
int num = n ;
while( true ){
if( !num || !T ) break ;
if( T >= sum ){
LL tmp = T / sum ;
T -= tmp * sum ;
res += tmp * num ;
}else{
for( int i = 0 ; i < n ; i++ ){
if( vis[i] ) continue ;
if( T >= a[i] ){
T -= a[i] ;
res ++ ;
}else{
sum -= a[i] ;
vis[i] = 1 ;
num -- ;
}
}
}
}
cout << res << endl;
return 0 ;
}
E
题意:求L到R范围内数字中,出现不同数字(0-9)个数<=k的数字(L-R)之和。
思路:数位dp, dp[i][j] 记录到i位 10个数字哪个数字出现过的状态,用二进制记录。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 1e2 + 6 ;
const int MOD = 998244353 ;
int a[AX] ;
LL l , r ;
int k ;
struct Node{
LL num ;
LL sum ;
Node(){
num = -1 ;
sum = 0 ;
}
Node( LL num , LL sum ):num(num),sum(sum){}
}dp[AX][1050] ;
LL c[AX] ;
Node dfs( int pos , int sta , bool lim ){
if( pos == -1 ) return Node( 1 , 0 ) ;
if( !lim && ~dp[pos][sta].num ) return dp[pos][sta] ;
Node ans = Node( 0 , 0 ) ;
int up = lim ? a[pos] : 9 ;
for( int i = 0 ; i <= up ; i++ ){
int nowsta = 0 ;
if( !sta && !i ){
nowsta = 0 ;
}else nowsta = sta | (1<<i) ;
if( __builtin_popcount(nowsta) > k ) continue ;
Node tmp = dfs( pos - 1 , nowsta , lim && i == a[pos] ) ;
ans.num = ( ans.num + tmp.num ) % MOD ;
ans.sum = ( ans.sum + tmp.sum + 1LL * tmp.num * c[pos] % MOD * i % MOD ) % MOD ;
}
if( !lim ) dp[pos][sta] = ans ;
return ans ;
}
void init(){
c[0] = 1;
for( int i = 1 ; i < 20 ; i++ ){
c[i] = (c[i-1]*10) % MOD ;
}
}
LL solve( LL x ){
int tot = 0 ;
while( x ){
a[tot++] = x % 10 ;
x /= 10 ;
}
return dfs( tot - 1 , 0 , true ).sum ;
}
int main(){
init() ;
cin >> l >> r >> k ;
cout << ( solve(r) - solve(l-1) + MOD ) % MOD ;
return 0 ;
}