文章目录
- A - Health M Death
- B - Many Oranges
- C - Comma
- D - Shipping Center
- E - Lucky 7 Battle
- F - Coprime Present
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
直接1e3,1e6,1e9,1e12,1e151e3,1e6,1e9,1e12,1e151e3,1e6,1e9,1e12,1e15做分界线求
#include <cstdio>
#define ll long longint 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
倒着推,dp[n]={0}dp[n]=\{0\}dp[n]={0},如果最终0∈dp00∈dp_00∈dp0就胜利
如果上一次操作是TTT,有一种情况可以达到,那么该余数就可以
dpi={r∣r∗10%7∈dpi+1⋃(r∗10+si+1)%7∈dpi+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}
如果上一次操作是AAA,必须所有情况都达到,该余数才可以
dpi={r∣r∗10%7∈dpi+1⋂(r∗10+si+1)%7∈dpi+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];elsedp[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
差值只有727272,所以∀x>72,x\forall_{x>72},x∀x>72,x的倍数最多只能出现一次,本质是构成其的质数最多只能出现一次
727272内的质数恰好202020个,两两互质,就相当于各个质数只出现一次
用状压DPDPDP完事
#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;
}