版权声明:本文为博主原创文章,未经博主允许也可以转载。 https://blog.csdn.net/FrankAx/article/details/82669676
A
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int main(){
LL n , k ;
cin >> n >> k ;
n = 2 * n + 1 ;
n -- ;
n /= 2 ;
LL num = k / n ;
k %= n ;
if( k ) num ++ ;
cout << num << endl;
return 0 ;
}
B
题意:从(0,0)走到(x,y) , 可以向上下左右左上左下右上右下这几个方向走,求用k步,最大能够斜着走的次数。k步(不多不少)不能达到则输出-1.
思路:可以处理成起点与终点(x,y)在一个对角线的问题,如果此时k-y是偶数步,那么到达终点时只需要一直沿着对角线来回走动即可。如果是奇数步,那么就在前面增减斜着走的数量以构造偶数。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
int main(){
LL k ;
int q ;
ios_base::sync_with_stdio(false); cin.tie(0) ; cout.tie(0) ;
LL x , y ;
cin >> q ;
while( q-- ){
LL num = 0LL ;
cin >> x >> y >> k ;
if( x > k || y > k ){
cout << -1 << endl;
}else{
if( x < y ) swap(x , y);
LL tmp = x - y ;
num += tmp ;
k -= tmp ;
if( k < 0 ) cout << -1 << endl;
if( tmp % 2 ){
if( k < y ){
cout << -1 << endl; continue;
}
k -- ;
if( (k-y) % 2 ){
k ++ ;
num -- ;
}
}else{
if( k < y ){
cout << -1 << endl; continue;
}
if( (k-y) % 2 ){
if( !tmp ){
k -= 2;
}else{
num -- ;
k -- ;
}
}
}
num += k ;
if( k < 0 || num < -1 ) cout << -1 << endl;
else cout << num << endl;
}
}
return 0 ;
}
C
题意:找出x-y中(包含x,y)除0以外数字少于等于3个的数的个数。
思路:数位dp,dp[pos][num]表示到pos位有num个非零数字。记得处理前导零即可。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 20+6;
int a[AX];
LL dp[AX][5];
LL dfs( int pos , int num , bool lead , bool lim ){
if( pos == -1 ) return 1;
if( !lim && !lead && dp[pos][num] != -1 ) return dp[pos][num];
LL ans = 0;
int up = lim ? a[pos] : 9 ;
for( int i = 0 ; i <= up ; i++ ){
if( num < 3 ){
if( lead && !i ) ans += dfs( pos - 1 , num , lead, lim && i == a[pos]);
else {
if( !i ) ans += dfs( pos - 1 , num , lead && i == 0 , lim && i == a[pos] );
else ans += dfs( pos - 1 , num + 1 , lead && i == 0 , lim && i == a[pos] );
}
}else if( num == 3 ){
if( !i ) ans += dfs( pos - 1 , num , lead && i == 0 , lim && i == a[pos] );
}
}
if( !lim && !lead ) dp[pos][num] = ans;
return ans ;
}
LL solve( LL x ){
int tot = 0 ;
while( x ){
a[tot++] = x % 10;
x /= 10;
}
return dfs( tot - 1 , 0 , true , true );
}
int main(){
int T;
ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ;
cin >> T ;
LL l , r ;
memset( dp , -1 , sizeof(dp) ) ;
while( T-- ){
cin >> l >> r ;
cout << ( solve(r) - solve(l-1) ) << endl;
}
return 0 ;
}
D
题意:给2个数组,可以将连续的一段相加,要求求出最大长度,使得a和b数组完全一样。
思路:双指针模拟即可。
Code:
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int AX = 3e5+666;
LL a[AX];
LL b[AX];
int main(){
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0) ;
int n , m ;
cin >> n ;
for( int i = 0; i < n ; i++ ){
cin >> a[i] ;
}
cin >> m ;
for( int i = 0 ; i < m ; i++ ){
cin >> b[i] ;
}
int cur_a = 0 , cur_b = 0 ;
int len = n ;
int len1 = m ;
while( cur_a < n && cur_b < m ){
if( a[cur_a] < b[cur_b] ){
LL tmp = a[cur_a] ;
while( cur_a < n && tmp < b[cur_b] ){
cur_a ++ ;
tmp += a[cur_a] ;
len -- ;
}
a[cur_a] = tmp ;
}else if( a[cur_a] > b[cur_b] ){
LL tmp = b[cur_b] ;
while( cur_b < m && tmp < a[cur_a] ){
cur_b ++ ;
tmp += b[cur_b] ;
len1 -- ;
}
b[cur_b] = tmp ;
}else{
cur_b ++ ;
cur_a ++ ;
}
}
if( len == len1 && a[cur_a] == b[cur_b] ) cout << len << endl;
else cout << -1 << endl;
return 0 ;
}