文章目录
Panasonic Programming Contest (AtCoder Beginner Contest 195)
A - Health M Death
判断倍数。
#include <cstdio>
int main() {
int M, H;
scanf( "%d %d", &M, &H );
if( H % M == 0 ) printf( "Yes\n" );
else printf( "No\n" );
return 0;
}
B - Many Oranges
橘子重量可以不是整数
-
最少个
尽量每个橘子都是最大重量
此外剩下一点重量,就再弄一个橘子,然后均分重量
-
最多个
尽量每个橘子都是最小重量
此外剩下一点重量,直接均分到每个橘子上
#include <cstdio>
#include <cmath>
using namespace std;
int A, B, n;
int main() {
scanf( "%d %d %d", &A, &B, &n );
n *= 1000;
int min_tot = n / A, max_tot = n / B;
int min_R = n - min_tot * A, max_R = n - max_tot * B;
int t;
t = int( ceil( ( A - min_R ) * 1.0 / min_tot ) );
if( min_R && t + A > B ) return ! printf( "UNSATISFIABLE\n" );
t = int( ceil( ( A - max_R ) * 1.0 / max_tot ) ) ;
if( max_R && B - t < A ) return ! printf( "UNSATISFIABLE\n" );
printf( "%d %d\n", max_tot + ( max_R ? 1 : 0 ), min_tot );
return 0;
}
C - Comma
直接 1 e 3 , 1 e 6 , 1 e 9 , 1 e 12 , 1 e 15 1e3,1e6,1e9,1e12,1e15 1e3,1e6,1e9,1e12,1e15做分界线求
#include <cstdio>
#define ll long long
int main() {
ll n;
ll x1 = 1e3, x2 = 1e6, x3 = 1e9, x4 = 1e12, x5 = 1e15;
scanf( "%lld", &n );
if( n < x1 ) return ! printf( "0" );
else if( n < x2) return ! printf( "%lld", n - x1 + 1 );
else if( n < x3 ) return ! printf( "%lld", x2 - x1 + ( n - x2 + 1 ) * 2ll );
else if( n < x4 ) return ! printf( "%lld", ( x3 - x2 ) * 2ll + x2 - x1 + ( n - x3 + 1 ) * 3ll );
else if( n < x5 ) return ! printf( "%lld", ( x4 - x3 ) * 3ll + ( x3 - x2 ) * 2ll + x2 - x1 + ( n - x4 + 1 ) * 4ll );
else return ! printf( "%lld", ( x5 - x4 ) * 4ll + ( x4 - x3 ) * 3ll + ( x3 - x2 ) * 2ll + x2 - x1 + ( n - x5 + 1 ) * 5ll );
return 0;
}
D - Shipping Center
每个包只能装一袋垃圾
贪心,先装价值最大的垃圾,用最小的能用空间
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 55
struct node {
int w, v;
}bag[maxn], box[maxn];
int n, m, Q;
int x[maxn];
bool vis[maxn];
bool cmp1( node x, node y ) {
return x.v > y.v;
}
bool cmp2( node x, node y ) {
return x.v < y.v;
}
int main() {
scanf( "%d %d %d", &n, &m, &Q );
for( int i = 1;i <= n;i ++ )
scanf( "%d %d", &bag[i].w, &bag[i].v );
for( int i = 1;i <= m;i ++ )
scanf( "%d", &box[i].v ), box[i].w = i;
sort( bag + 1, bag + n + 1, cmp1 );
sort( box + 1, box + m + 1, cmp2 );
while( Q -- ) {
int l, r;
scanf( "%d %d", &l, &r );
int ans = 0;
for( int i = l;i <= r;i ++ ) vis[i] = 1;
for( int i = 1;i <= n;i ++ )
for( int j = 1;j <= m;j ++ )
if( vis[box[j].w] || box[j].v < bag[i].w ) continue;
else {
vis[box[j].w] = 1;
ans += bag[i].v;
break;
}
for( int i = 1;i <= m;i ++ ) vis[i] = 0;
printf( "%d\n", ans );
}
return 0;
}
E - Lucky 7 Battle
倒着推, d p [ n ] = { 0 } dp[n]=\{0\} dp[n]={0},如果最终 0 ∈ d p 0 0∈dp_0 0∈dp0就胜利
如果上一次操作是 T T T,有一种情况可以达到,那么该余数就可以
d p i = { r ∣ r ∗ 10 % 7 ∈ d p i + 1 ⋃ ( r ∗ 10 + s i + 1 ) % 7 ∈ d p i + 1 } dp_i=\{r\ |\ r*10\%7∈dp_{i+1}\ \bigcup\ (r*10+s_{i+1})\%7∈dp_{i+1}\} dpi={r ∣ r∗10%7∈dpi+1 ⋃ (r∗10+si+1)%7∈dpi+1}
如果上一次操作是 A A A,必须所有情况都达到,该余数才可以
d p i = { r ∣ r ∗ 10 % 7 ∈ d p i + 1 ⋂ ( r ∗ 10 + s i + 1 ) % 7 ∈ d p i + 1 } dp_i=\{r\ |\ r*10\%7∈dp_{i+1}\ \bigcap\ (r*10+s_{i+1})\%7∈dp_{i+1}\} dpi={r ∣ r∗10%7∈dpi+1 ⋂ (r∗10+si+1)%7∈dpi+1}
#include <cstdio>
#include <iostream>
using namespace std;
#define maxn 200005
int n;
char s[maxn], x[maxn];
int dp[maxn][7];
int main() {
scanf( "%d %s %s", &n, s + 1, x + 1 );
dp[n][0] = 1;
for( int i = n - 1;~ i;i -- )
for( int r = 0;r < 7;r ++ )
if( x[i + 1] == 'T' )
dp[i][r] = dp[i + 1][r * 10 % 7] | dp[i + 1][( r * 10 + ( s[i + 1] ^ 48 ) ) % 7];
else
dp[i][r] = dp[i + 1][r * 10 % 7] & dp[i + 1][( r * 10 + ( s[i + 1] ^ 48 ) ) % 7];
if( dp[0][0] ) printf( "Takahashi\n" );
else printf( "Aoki\n" );
return 0;
}
F - Coprime Present
差值只有 72 72 72,所以 ∀ x > 72 , x \forall_{x>72},x ∀x>72,x的倍数最多只能出现一次,本质是构成其的质数最多只能出现一次
72 72 72内的质数恰好 20 20 20个,两两互质,就相当于各个质数只出现一次
用状压 D P DP DP完事
#include <cstdio>
#define int long long
#define maxn 1050000
int prime[20] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71 };
int dp[maxn];
int A, B;
signed main() {
scanf( "%lld %lld", &A, &B );
dp[0] = 1;
for( int i = A;i <= B;i ++ ) {
int t = 0;
for( int j = 0;j < 20;j ++ )
if( i % prime[j] == 0 )
t |= ( 1 << j );
for( int s = 0;s < ( 1 << 20 );s ++ )
if( ! ( s & t ) ) dp[s | t] += dp[s];
}
int ans = 0;
for( int i = 0;i < ( 1 << 20 );i ++ )
ans += dp[i];
printf( "%lld\n", ans );
return 0;
}