题目链接

A - On The Way to Lucky Plaza

首先,$n>m$或$k>m$或$k>n$就无解。

设$p = \frac{A}{B}$,$ans = C_{n - 1}^{k - 1}{\left( {\frac{A}{B}} \right)^{k}}{\left( {\frac{B-A}{B}} \right)^{n - k}} = \frac{{\left( {n - 1} \right)! \times {A^k} \times {{\left( {B - A} \right)}^{n - k}}}}{{\left( {k - 1} \right)! \times \left( {n - k} \right)! \times {B^n}}}$。令分子为$p$,分母为$q$,最终的答案为$p$*($q$的逆元)。

#include <bits/stdc++.h>
using namespace std; const long long mod = 1e9 + 7;
const int maxn = 2e5 + 10;
long long f[maxn]; long long m, n, k;
char s[maxn]; long long qpow(long long a, long long b) {
long long res = 1LL;
a = a % mod;
while(b) {
if(b & 1) res = (res * a) % mod;
b = b / 2;
a = (a * a) % mod;
}
return res;
} long long extend_gcd(long long a,long long b,long long &x,long long &y)
{
if(a==0&&b==0) return -1;//无最大公约数
if(b==0){x=1;y=0;return a;}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
//*********求逆元素*******************
//ax = 1(mod n)
long long mod_reverse(long long a,long long n)
{
long long x,y;
long long d=extend_gcd(a,n,x,y);
if(d==1) return (x%n+n)%n;
else return -1;
} void init() {
f[0] = 1LL;
for(long long i = 1; i <= 100000; i ++) {
f[i] = (f[i - 1] * i) % mod;
}
} int main() {
init();
cin >> m >> n >> k >> s;
if(n > m || k > m || k > n) {
printf("0\n");
return 0;
}
if(s[0] == '1' && n == k) {
printf("1\n");
return 0;
}
if(s[0] == '1') {
printf("0\n");
return 0;
}
if(s[0] == '0' && s[2] == '0' && s[3] == '0' && s[4] == '0') {
printf("0\n");
return 0;
} long long A = 0;
long long B = 1000LL;
for(int i = 2; i <= 4; i ++) {
A = A * 10LL + s[i] - '0';
} long long p, q; p = f[n - 1] * qpow(A, k) % mod;
p = p * qpow(B - A, n - k) % mod; q = f[k - 1] * f[n - k] % mod;
q = q * qpow(B, n) % mod; long long x = p * mod_reverse(q, mod) % mod;
printf("%lld\n", x);
return 0;
}

B - So You Think You Can Count?

设$dp[i]$表示以$i$为结尾的方案数,每个位置最多往前扫$10$位。

#include <bits/stdc++.h>
using namespace std; const long long mod = 1e9 + 7;
const int maxn = 1e5 + 10;
char s[maxn];
int n;
long long dp[maxn]; long long DP(int x) {
if(x < 0) return 1LL;
return dp[x];
} int main() {
scanf("%d", &n);
scanf("%s", s);
int len = strlen(s);
dp[0] = 1LL;
for(int i = 1; i < len; i ++) {
int tmp[20];
for(int j = 0; j <= 9; j ++) {
tmp[j] = 0;
}
for(int pre = i; pre >= 0; pre --) {
if(tmp[s[pre] - '0']) break;
tmp[s[pre] - '0'] = 1;
dp[i] = (dp[i] + DP(pre - 1)) % mod;
}
}
printf("%lld\n", dp[len - 1]);
return 0;
}

C - MRT Map

最短路,数据有点水,没把spfa卡住。

#include <bits/stdc++.h>
using namespace std; const int maxn = 2e5 + 10; int S, T, n, m;
char name[maxn][25];
int h[maxn], nx[maxn], to[maxn], c[maxn], sz;
int t1[30], t2[30]; int cost(int x, int y) {
memset(t1, 0, sizeof t1);
memset(t2, 0, sizeof t2); for(int i = 0; name[x][i]; i ++){
if(name[x][i] >= 'a' && name[x][i] <= 'z') {
t1[name[x][i] - 'a'] ++;
}
if(name[x][i] >= 'A' && name[x][i] <= 'Z') {
t1[name[x][i] - 'A'] ++;
}
} for(int i = 0; name[y][i]; i ++){
if(name[y][i] >= 'a' && name[y][i] <= 'z') {
t2[name[y][i] - 'a'] ++;
}
if(name[y][i] >= 'A' && name[y][i] <= 'Z') {
t2[name[y][i] - 'A'] ++;
}
} int num = 0;
for(int i = 0; i < 26; i ++) {
if(t1[i] && t2[i]) num ++;
}
return num;
} void add(int x, int y, int z) {
to[sz] = y;
c[sz] = z;
nx[sz] = h[x];
h[x] = sz++;
} int dis[maxn], f[maxn]; void spfa() {
for(int i = 1 ;i <= n; i ++) {
f[i] = 0;
dis[i] = 0x7FFFFFFF;
}
queue<int> Q;
Q.push(S);
f[S] = 1;
dis[S] = 0;
while(!Q.empty()) {
int top = Q.front();
Q.pop();
f[top] = 0;
for(int i = h[top]; i != -1; i = nx[i]) {
if(dis[top] + c[i] < dis[to[i]]) {
dis[to[i]] = dis[top] + c[i];
if(f[to[i]] == 0) {
f[to[i]] = 1;
Q.push(to[i]);
}
}
}
}
} int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++) {
scanf("%s", name[i]);
h[i] = -1;
}
for(int i = 1; i <= m; i ++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v, cost(u, v));
add(v, u, cost(u, v));
}
scanf("%d%d", &S, &T);
spfa();
printf("%d\n", dis[T]);
return 0;
}

D - Husam's Bug

模拟。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e6 + 10;
char s[maxn]; int main() {
int T;
scanf("%d", &T);
while(T --) {
scanf("%s", s); int num1=0, num2=0, num3=0;
for(int i = 0; s[i];i ++) {
if(s[i]>='a'&&s[i]<='z') num1++;
else if(s[i]>='A'&&s[i]<='Z') num1++;
else if(s[i]>='0'&&s[i]<='9') num2++;
else if(s[i] =='!' || s[i] =='?'||s[i] == '@') {
num3++;
}
}
if(num1 < 4) {
printf("The last character must be a letter.\n");
continue;
}
if(num2 < 4) {
printf("The last character must be a digit.\n");
continue;
}
if(num3 < 2) {
printf("The last character must be a symbol.\n");
continue;
}
printf("The last character can be any type.\n");
}
return 0;
}

E - Abdalrahman Ali Bugs

由于验证的复杂度只有$O(26)$,因此可以枚举答案。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int n, m;
char s[maxn];
long long f[maxn]; int main() {
scanf("%s", s);
for(int i = 0; s[i]; i ++) {
f[s[i] - 'a'] ++;
}
long long ans = -1;
long long mn = -1;
for(long long i = 2; i <= 300000; i ++) {
long long tmp = 0;
for(int j = 0; j < 26; j ++) {
tmp = tmp + (f[j] % i) * f[j];
}
if(mn == -1 || tmp < mn) {
mn = tmp;
ans = i;
}
}
printf("%lld\n", ans);
return 0;
}

F - Certifications

二分查找。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1e5 + 10;
int n, m;
int a[maxn]; int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
sort(a + 1, a + 1 + n);
scanf("%d", &m);
while(m --) {
int x;
scanf("%d", &x);
int L = 1, R = n, pos = -1;
while(L <= R) {
int mid = (L + R) / 2;
if(a[mid] >= x) pos = mid, R = mid - 1;
else L = mid + 1;
}
if(pos == -1) printf("Dr. Samer cannot take any offer :(.\n");
else printf("%d\n", a[pos]);
}
return 0;
}

G - In the Chairman's office

模拟。

#include <bits/stdc++.h>
using namespace std; int main() {
int n, m;
cin>> n>>m;
if(m % n == 0) printf("YES\n");
else printf("NO\n");
return 0;
}

H - Give Me This Pizza

这题为单调栈经典问题,但是由于数值范围只有$50$,因此可以枚举数值。

#include <bits/stdc++.h>
using namespace std; const int maxn = 2e5 + 10;
int n, m;
int a[maxn];
int b[maxn];
int num[maxn]; int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%d", &a[i]);
}
for(int i = 0; i<= 100; i ++) num[i] = 200000;
for(int j = n; j>=1; j--) {
b[j] = 200000;
for(int k = 50; k >= a[j] + 1; k--){
if(num[k] < b[j]) b[j] = num[k];
}
num[a[j]] = j;
if(b[j] != 200000) b[j] = a[b[j]];
else b[j] = -1;
}
for(int i =1 ;i <= n; i ++) {
printf("%d ", b[i]);
}
return 0;
}

I - Husam and the Broken Present 1

对主对角线开根号来求解。

#include <bits/stdc++.h>
using namespace std; int main() {
int n;
cin>> n;
int x;
for(int i = 1; i <= n; i ++) {
for(int j = 1; j <= n; j++){
cin>>x;
if(i == j){
int num = sqrt(1.0 * x);
while(num * num > x) num--;
while(num*num<x)num++;
printf("%d ", num);
} }
}
return 0;
}

J - Husam and the Broken Present 2

先删除被包含的那些数组,剩下的可以进行状压$dp$来决策放置顺序。$dp[st][v]$表示有$st$状态里面的子数组已经放置好了,最后放的是$v$的最小花费,和TSP是一样的问题。

#include <bits/stdc++.h>
using namespace std; const int maxn = 1000;
vector<int> vec[maxn], t[maxn];
int cost[20][20]; int n;
int dp[70000][17]; int han(vector<int>& a, vector<int>& b) {
// a 是否在 b 中
if(b.size() < a.size()) return 0;
for(int i = 0; i < b.size(); i ++) {
int L = i, R = i + a.size() - 1;
if(R >= b.size()) break;
int fail = 0;
for(int j = 0; j < a.size(); j ++) {
if(a[j] != b[L + j]) fail = 1;
}
if(fail == 0) return 1;
}
return 0;
} int cal(int x, int y) {
// x 后面 接 y
int res = 0;
for(int i = 0; i < t[x].size(); i ++) {
if(t[x].size() - i > t[y].size()) continue;
int fail = 0;
for(int j = i; j < t[x].size(); j ++) {
if(t[x][j] != t[y][j - i]) fail = 1;
}
//printf("!!! %d, %d\n", i, fail);
if(fail == 0) {
res = t[x].size() - i;
break;
} }
return t[y].size() - res;
} bool cmp(const vector<int> &a, const vector<int> &b) {
return a.size() > b.size();
} int main() {
scanf("%d", &n);
for(int i = 0; i < n; i ++) {
int x;
scanf("%d", &x);
while(x--){
int p;
scanf("%d", &p);
vec[i].push_back(p);
}
}
sort(vec, vec + n, cmp);
int sz = 0;
t[sz++] = vec[0];
for(int i = 1; i < n; i ++) {
int fail = 0;
for(int j = 0; j < sz; j ++) {
if(han(vec[i], t[j])) {
fail = 1;
break;
}
}
if(fail) continue;
t[sz ++] = vec[i];
} n = sz; /*
for(int i = 0; i < n; i ++) {
for(int j = 0; j < t[i].size(); j ++) {
cout << t[i][j] << " ";
}
cout << endl;
}
*/ for(int i = 0; i < n; i ++) {
for(int j = 0; j < n; j ++) {
if(i == j) continue;
cost[i][j] = cal(i, j);
}
} for(int st = 0; st < (1 << n); st ++) {
for(int i = 0; i < n; i ++) {
dp[st][i] = 200000;
}
}
for(int i = 0; i < n; i ++) {
dp[1 << i][i] = t[i].size();
} for(int st = 1; st < (1 << n); st ++) {
for(int pre = 0; pre < n; pre ++) {
if(((1 << pre) & st) == 0) continue;
for(int now = 0; now < n; now ++) {
if((1 << now) & st) continue;
dp[st | (1 << now)][now] = min(dp[st | (1 << now)][now], dp[st][pre] + cost[pre][now]);
}
}
} int ans = dp[(1 << n) - 1][0];
for(int i = 0; i < n; i ++) {
ans = min(ans, dp[(1 << n) - 1][i]);
}
printf("%d\n", ans); return 0;
} /*
3
2 1 2
4 3 4 5 6
3 2 3 4 */

2017 JUST Programming Contest 2.0 题解的更多相关文章

  1. gym101343 2017 JUST Programming Contest 2.0

    A.On The Way to Lucky Plaza  (数论)题意:m个店 每个店可以买一个小球的概率为p       求恰好在第m个店买到k个小球的概率 题解:求在前m-1个店买k-1个球再*p ...

  2. 2018 JUST Programming Contest 1.0 题解

    题目链接  gym101778 Problem A 转化成绝对值之后算一下概率.这个题有点像 2018 ZOJ Monthly March Problem D ? 不过那个题要难一些~ #includ ...

  3. gym101532 2017 JUST Programming Contest 4.0

    台州学院ICPC赛前训练5 人生第一次ak,而且ak得还蛮快的,感谢队友带我飞 A 直接用claris的模板啊,他模板确实比较强大,其实就是因为更新的很快 #include<bits/stdc+ ...

  4. 2017 JUST Programming Contest 3.0 B. Linear Algebra Test

    B. Linear Algebra Test time limit per test 3.0 s memory limit per test 256 MB input standard input o ...

  5. 2017 JUST Programming Contest 3.0 I. Move Between Numbers

    I. Move Between Numbers time limit per test 2.0 s memory limit per test 256 MB input standard input ...

  6. 2017 JUST Programming Contest 3.0 D. Dice Game

    D. Dice Game time limit per test 1.0 s memory limit per test 256 MB input standard input output stan ...

  7. 2017 JUST Programming Contest 3.0 H. Eyad and Math

    H. Eyad and Math time limit per test 2.0 s memory limit per test 256 MB input standard input output ...

  8. 2017 JUST Programming Contest 3.0 K. Malek and Summer Semester

    K. Malek and Summer Semester time limit per test 1.0 s memory limit per test 256 MB input standard i ...

  9. 2017 JUST Programming Contest 3.0 E. The Architect Omar

    E. The Architect Omar time limit per test 1.0 s memory limit per test 256 MB input standard input ou ...

随机推荐

  1. 【bzoj2875】 Noi2012—随机数生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=2875 (题目链接) 题意 求${X_{n}}$. Solution 矩乘板子,这里主要讲下会爆lon ...

  2. eclipse/intellij idea 查看java源码和注释

    工作三年了,一直不知道怎么用IDE查看第三方jar包的源码和注释,惭愧啊!看源码还好些,itellij idea自带反编译器,eclipse装个插件即可,看注释就麻烦了,总不能去找api文档吧!现在终 ...

  3. 界面编程之QT的Socket通信20180730

    /*******************************************************************************************/ 一.linu ...

  4. C++原型模式和模板模式

    DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.其中有一个词很重要,那就是拷贝.可以说,拷贝是原型模式的精髓所在.举个现实中的例子来介绍原型模式.找工作的时候,我们需 ...

  5. Hadoop生态圈-Flume的主流source源配置

    Hadoop生态圈-Flume的主流source源配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是配置的是Flume主流的Source,想要了解更详细的配置信息请参 ...

  6. Linux文本处理工具——Sed

    sed:数据流编辑器: awk:报告文本的生成器 sed 基本用法:(Stream EDitor) Stream 流 EDitor 编辑器 行编辑器 全屏编辑器:vi/vimsed:内存空间(模式空间 ...

  7. Algorithm(1) - Karatsuba multiplication

    这个系列主要是记一下目前效率较高或者比较出名的一些算法. Karatsuba multiplication: x=5678   then: a=56  b=67 y=1234           c= ...

  8. 20155216 2016-2017-2 《Java程序设计》第八周学习总结

    20155216 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 认识NIO Java NIO 由以下几个核心部分组成: Channels Buffers S ...

  9. tf.Session()和tf.InteractiveSession()的区别

    官方tutorial是这么说的: The only difference with a regular Session is that an InteractiveSession installs i ...

  10. 第10月第21天 手势识别 开屏广告 Xcode快捷键

    1.手势识别 http://yulingtianxia.com/blog/2016/12/29/Multimedia-Edit-Module-Architecture-Design/ 2.开屏广告 h ...