【题目链接】

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. 【POJ3171】Cleaning Shifts 带权区间最小覆盖

    题目大意:给定一个长度为 N 的序列,求带权区间最小覆盖. 题解:设 \(dp[i]\) 表示从左端点到 i 的最小权值是多少,则状态转移为:\(dp[e[i].ed]=min\{dp[j],j\in ...

  2. 一文掌握Docker Compose

    目录 Docker Compose介绍 Docker Compose安装 Docker Compose基本示例 1.基本文件及目录设置 2.创建一个Dockerfile 3.通过docker-comp ...

  3. vue父组件调用子组件资源

    通过上篇博文提到的方法我们可以触发子组件的某个事件来实现调用子组件的某些资源(例如数据和方法),但是更多的情况下我们会想不通过触发子组件的事件,而直接调用子组件的资源 这个时候我们就需要用到ref了, ...

  4. 在“安装”阶段发生异常。 System.Security.SecurityException: 未找到源,但未能

    写Windows服务的时候,运行了一下,就是没反应,命令框一闪而过,查了一下异常,大致是题目的那样.原因是因为权限不足.但是在网上搜的方法都不顶用. 解决方法如下: (1)以管理员身份运行CMD: ( ...

  5. CCNA学习与实验指南——第2章 网络互联和参考模型

    大三下学期的这个时间段,不知道是不是社会就业的恐惧与自身前途的迷茫所带来的压力,身边的同学一个个的整天奔赴考研室学的好不努力,空荡荡的宿舍只剩我一人孑然聊聊甚是索然无味,亦或许是即将毕业的压力等接踵而 ...

  6. Spark记录-Scala多线程

    Scala多线程 多线程是同时执行多个线程的过程. 它允许您独立执行多个操作.可以通过使用多线程来实现多任务.线程是轻量级的子进程,占用较少的内存.多线程用于在Scala中开发并发应用程序. Scal ...

  7. SQL记录-PLSQL异常

    PL/SQL异常   程序执行过程中出现错误情况被称为在PL/SQL异常. PL/SQL支持程序员在程序中使用异常块捕获这样的条件并采取适当的动作应对错误情况.有两种类型的异常: 系统定义的异常 用户 ...

  8. Linux命令(七)Linux用户管理和修改文件权限

    1. 用户管理 1.1 创建用户/设置密码/删除用户 (-m很重要,自动添加用户家目录) 创建用户组dev, 给用户组dev新建xiaoqin用户,给新用户设置密码! 1.2 查看用户信息 1.3 设 ...

  9. 线性筛的同时得到欧拉函数 (KuangBin板子)

    线性筛的思想:每个被筛的数是通过它最小的质因子所筛去的. 这种思想保证了每个数只会被筛一次,从而达到线性.并且,这个思想实现起来非常巧妙(见代码注释)! 因为线性筛的操作中用到了倍数的关系去实现,因此 ...

  10. win8开wifi共享无法使用的问题解决办法

    相信现在不少人都安装了windows8操作系统,因为windows8这个全新的操作系统用起来 确实挺强大,包括漂亮的开始屏,但是不得不说这个系统的兼容性还是有待提高,所以win8我的 装了又卸,卸了又 ...