AtCoder Beginner Contest 271
A - 484558
十进制转十六进制,签到题
#include<bits/stdc++.h>
#define int long long
using namespace std;
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;
}
void print( int x ){
if( x < 10 )
cout << x ;
else
cout << char( x - 10 + 'A' );
}
int32_t main(){
int n , a , b;
cin >> n;
b = n % 16;
a = n / 16;
print(a) , print(b);
return 0;
}
B - Maintain Multiple Sequences
读入多行数字,每次询问某一行某一列的数字,保证询问合法,这道题实际上很简单但是直接搞的话开不了呢么大的数组,用vector
替代一下就好了
#include<bits/stdc++.h>
#define int long long
using namespace std;
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;
}
const int N = 2e5+5;
int32_t main(){
int n = read() , q = read();
vector a = vector< vector<int> >(n+1);
for( int i = 1 , l ; i <= n ; i ++ ){
l = read() , a[i].push_back(0);
for( int j = 1 , x ; j <= l ; j ++ )
x = read() , a[i].push_back(x);
}
for( int i , j ; q ; q -- ){
i = read() , j = read();
cout << a[i][j] << '\n';
}
}
C - Manga
他有n
本书,他可以卖掉任意两本,再购买一本新的,他必须从第一本开始看,依次看第二第三第四,问他最多可以看多少本书
首先重复的书都可以卖掉,其次如果当前要看的书没有可以卖掉后面的书来购买当前的数,贪心一下知道卖掉最后两本最优。
#include<bits/stdc++.h>
#define int long long
using namespace std;
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;
}
set<int> s;
int32_t main(){
int n = read() , cnt = 0;
for( int x ; n ; n -- ){
x = read();
if( s.count(x) ) cnt ++;
else s.insert(x);
}
for( int i = 1 ; i ; i ++ ){
if( s.count(i) ) s.erase(i);
else{
if( cnt >= 2 ) cnt -= 2;
else if ( cnt >= 1 && s.size() >= 1 ){
cnt -- , s.erase( *s.rbegin() );
}
else if( s.size() >= 2 ) {
s.erase( *s.rbegin() ) , s.erase( *s.rbegin() );
}
else cout << i-1 , exit(0);
}
}
}
D - Flip and Adjust
有N
张卡片,正反面分别是A
和B
,问是否可以在每张卡片都用的情况下组合出S
一道很基础的搜索加剪枝的题目。
通过 dfs 枚举选择那一面,然后i,sum
表示选择到第i
张卡片,且和为sum
。把所有的状态插入到set
中,如果之前出现过了,再次遇到就不用搜索了,因为后面的情况是完全相同的。
然后统计一下后缀最大值和后缀最小值,然后判断当前情况下,继续先后搜索是否可以包含S
以上两种剪枝就可以过这道题了
#include<bits/stdc++.h>
#define int long long
using namespace std;
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;
}
const int N = 105;
int n , s , top , down;
int a[N] , b[N] , c[N] , d[N];
set< pair<int,int> > st;
bitset<N> sta;
void dfs( int i , int sum ){
if( st.count( { i , sum } ) ) return;
st.insert( { i , sum } );
if( sum + c[i] < s || sum + d[i] > s ) return;
if( i == n + 1 ){
if( sum == s ){
cout << "Yes\n";
for( int j = 1 ; j <= n ; j ++ )
cout << (sta[j]?'H':'T');
exit(0);
}
return;
}
sta[i] = 1 , dfs( i + 1 , sum + a[i] );
sta[i] = 0 , dfs( i + 1 , sum + b[i] );
}
int32_t main(){
n = read() , s = read();
for( int i = 1 ; i <= n ; i ++ )
a[i] = read() , b[i] = read() , c[i] = max( a[i] , b[i] ) , d[i] = min( a[i] , b[i] );
for( int i = n ; i >= 1 ; i -- )
c[i] += c[i+1] , d[i] += d[i+1];
dfs( 1 , 0 );
cout << "No";
return 0;
}