2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) Solution
A:Concerts
题意:给出一个串T, 一个串S,求串S中有多少个串T,可以重复,但是两个字符间的距离要满足给出的数据要求
思路:先顺序统计第一个T中的字符在S中有多少个,然后对于第二位的以及后面的,我们从后面往前推,前缀和搞一搞,注意间距
#include<bits/stdc++.h> using namespace std; #define N 100010 typedef long long ll; const int MOD = 1e9 + ; ll sum[N]; char strN[N], strK[N]; int n,k;
int pos[]; int main()
{
while(~scanf("%d %d",&k,&n))
{
memset(sum, , sizeof sum);
for(int i = ; i < ; ++i)
{
scanf("%d",&pos[i]);
}
scanf("%s",strK + );
scanf("%s",strN + );
for(int i = ;i <= n; ++i)
{
sum[i] = (strN[i] == strK[]) + sum[i - ];
sum[i] %= MOD;
}
for(int i = ; i <= k; ++i)
{
for(int j = n; j >= ; --j)
{
if(strN[j] == strK[i])
{
int idx = strK[i - ] - 'A';
idx = pos[idx];
if(j - idx - < ) sum[j] = ;
else sum[j] = sum[j - idx - ];
}
else sum[j] = ;
}
for(int j = ;j <= n; ++j)
{
sum[j] += sum[j - ];
sum[j] %= MOD;
}
}
printf("%lld\n",sum[n]);
}
return ;
}
B:Bricks
留坑。
C:Christmas Tree
留坑。
D:Harry Potter and The Vector Spell
题意:给出n个向量,每个向量有m维,n个向量中有且只有两维上是一,然后重载了加号运算符和乘号运算符,求最多的非线性相关的向量个数
思路:因为每个向量中有且只有两个1,那么可以想象答案最大肯定是m - 1 因为分布肯定是这样的
那么我们考虑将每个向量的两个1连一条边,那么每个连通块对答案的贡献就是 连通块里面的点数减1
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h>
using namespace std; #define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define ll long long
#define N 100100 int m, n;
int pre[N];
int arr[N]; inline int find(int x)
{
if (x != pre[x])
pre[x] = find(pre[x]);
return pre[x];
} inline void join(int x, int y)
{
int fx = find(x), fy = find(y);
if (fx != fy)
pre[fx] = fy;
} inline void Run()
{
while (scanf("%d%d", &m, &n) != EOF)
{
memset(arr, , sizeof arr);
for (int i = ; i <= m; ++i)
pre[i] = i;
for (int i = , tot, x; i <= m; ++i)
{
scanf("%d", &tot);
while (tot--)
{
scanf("%d", &x);
if (arr[x])
join(arr[x], i);
else
arr[x] = i;
}
}
int cnt = ;
for (int i = ; i <= m; ++i)
if (pre[i] == i) ++cnt;
printf("%d\n", m - cnt);
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
E:Looping Playlist
留坑。
F:Binary Transformations
题意:给出两个01串,每位有一个权值,然后要从a串变成b串,每换一次的花费是变之后a串中里面每一位是1的对应的权值和,求最小花费
思路:贪心的想法
先把1变成0,按权值大小从大到小变,把0变成1,按权值从小到大变
存在一个问题,如果本来a对应的那位以及b对应的那位都是1,但是那位权值特别特别大,可以将它先变成0,最后再变回来,可能会使得花费更少
容易知道,如果将a里面所有为1位的权值从大到小排序,那么如果存在这样的方案使得花费减少,那么肯定是一段连续的,枚举长度,
时间复杂度O(n ^ 2)
注意随手剪枝
#include<bits/stdc++.h> using namespace std; typedef long long ll;
#define N 5010
const ll INFLL = 0x3f3f3f3f3f3f3f3f;
struct node{
int pos;
int cost;
inline node(){}
inline node(int pos,int cost) :pos(pos), cost(cost){}
inline bool operator < (const node &b) const
{
return cost > b.cost;
}
}; inline bool cmp1(node a, node b)
{
return a.cost > b.cost;
} inline bool cmp2(node a, node b)
{
return a.cost < b.cost;
} int n;
ll sum;
int cost[N];
char s1[N];
char s2[N]; int main()
{
while(~scanf("%d",&n))
{
for(int i = ; i <= n; ++i)
{
scanf("%d", &cost[i]);
}
sum = ;
scanf("%s", s1 + );
scanf("%s", s2 + );
vector<node>ONE, ZERO_ONE;
for(int i = ; i <= n; ++i)
{
if(s1[i] == '')
{
ONE.push_back(node(i, cost[i]));
sum += cost[i];
}
else if(s1[i] == '' && s2[i] == '')
{
ZERO_ONE.push_back(node(i, cost[i]));
}
}
sort(ONE.begin(), ONE.end(), cmp1);
int len = ONE.size();
ll Begin = sum;
ll ans = INFLL;
for(int sz = -; sz < len; ++sz)
{
ll tmp = ;
sum = Begin;
for(int i = ; i <= sz; ++i)
{
sum -= ONE[i].cost;
tmp += sum;
if(tmp >= ans) break;
}
if(tmp >= ans) continue;
for(int i = sz + ; i < len; ++i)
{
int p = ONE[i].pos;
if(s2[p] == '')
{
sum -= ONE[i].cost;
tmp += sum;
if(tmp >= ans) break;
}
}
if(tmp >= ans) continue;
vector<node>CHANGE = ZERO_ONE;
for(int i = ; i <= sz; ++i)
{
int p = ONE[i].pos;
if(s1[p] == '' && s2[p] == '')
{
CHANGE.push_back(node(p, cost[p]));
}
}
sort(CHANGE.begin(), CHANGE.end(), cmp2);
for(int i = , lenn = CHANGE.size(); i < lenn; ++i)
{
sum += CHANGE[i].cost;
tmp += sum;
if(tmp >= ans) break;
}
ans = min(ans, tmp);
}
printf("%lld\n",ans);
}
return ;
}
G:Robots
题意:给出n组数据,每组数据包含一个加速度和时间,求按顺序得到的距离,以及按最优顺序得到距离的不同
思路:先遍历一遍算一下,然后贪心按加速度排一下,算一下,算差距
#include <bits/stdc++.h> using namespace std; #define N 10010 struct node
{
double a, s;
inline void scan()
{
scanf("%lf%lf", &a, &s);
}
inline bool operator < (const node &r) const
{
return a > r.a;
}
}arr[N]; int n; inline double work()
{
double res = ;
double v = ;
for (int i = ; i <= n; ++i)
{
double t = arr[i].s;
res += v * t + arr[i].a * t * t / ;
v += arr[i].a * t;
}
return res;
} int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan();
double sum1 = work();
sort(arr + , arr + + n);
double sum2 = work();
// printf("%lf %lf\n", sum1, sum2);
printf("%.1f\n", sum2 - sum1);
}
return ;
}
H:Cat and Mouse
留坑。
I:Tetris
留坑。
J:Cunning Friends
题意:有n堆石头,第i堆有ai个,A先取,每次从一堆中取的数量不等于0,然后B 和 C取 谁不能取了谁就输了,B 和 C 想让A输,假设每个人的决策都是最佳的,求A是必败还是必输
思路:可以考虑一下几种情况
1° 全是1的情况 那么用n%3 看一下余数,如果余数是0 那么A是必输的
2°只有一个不是1的情况,那么A是必胜的,因为假如堆数%3 == 0 那么 我将不是1的那堆取成1,这样就相当于变成了堆数%3==1 变成必胜态
3°有两个不是1的情况
首先我们可以知道,假如只有两堆,并且这两堆都不是1,那么A是必输的
那转化成加了若干堆1,那么这若干堆1当中如果%3 == 0 那么A是必输的
如果不是,并且存在至少一堆是2,A是赢的
4° 其他情况都是必输的
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream> using namespace std; #define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define ll long long
#define N 100100 int n; int ONE, TWO; inline bool work()
{
if (ONE == n - ) return true;
else if (ONE == n)
return n % ;
if (ONE == n - )
{
if (n % == ) return false;
if (TWO) return true;
return false;
}
return false;
} inline void Run()
{
while (scanf("%d", &n) != EOF)
{
ONE = , TWO = ;
for (int i = , num; i <= n; ++i)
{
scanf("%d", &num);
if (num == ) ++ONE;
if (num == ) ++TWO;
}
puts(work() ? "Win" : "Lose");
}
} int main()
{
#ifdef LOCAL
freopen("Test.in", "r", stdin);
#endif Run(); return ;
}
k:Escape Room
题意:有一个长度为n的序列,里面的数是1 - n 然后给出每一位以当前位为队头的最长上升子序列长度,还原原序列,多个答案输出字典序最小的那个
思路:
比如说 1 2 2 1
我们可以考虑先放长度为1 的
肯定是从后面取两个数 放 4 和 3
然后 长度就变成
0 1 1 0
然后又取两个 2 1 放下去
#include <bits/stdc++.h> using namespace std; #define N 10010 struct node
{
double a, s;
inline void scan()
{
scanf("%lf%lf", &a, &s);
}
inline bool operator < (const node &r) const
{
return a > r.a;
}
}arr[N]; int n; inline double work()
{
double res = ;
double v = ;
for (int i = ; i <= n; ++i)
{
double t = arr[i].s;
res += v * t + arr[i].a * t * t / ;
v += arr[i].a * t;
}
return res;
} int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = ; i <= n; ++i) arr[i].scan();
double sum1 = work();
sort(arr + , arr + + n);
double sum2 = work();
// printf("%lf %lf\n", sum1, sum2);
printf("%.1f\n", sum2 - sum1);
}
return ;
}
L:Divide and Conquer
留坑。
2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) Solution的更多相关文章
- 2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017)
2017-2018 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2017) 全靠 wxh的博客 补完这套.wx ...
- 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018)
layout: post title: 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 201 ...
- 2018-2019 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2018) Solution
A. Numbers Unsolved. B. Broken Watch Solved. 题意: 一个圆盘上,有等分的n块区域,有三根指针,当三根指针分别位于两块区域的交界处时 指针的三点相连会形成一 ...
- Gym 2009-2010 ACM ICPC Southwestern European Regional Programming Contest (SWERC 2009) A. Trick or Treat (三分)
题意:在二维坐标轴上给你一堆点,在x轴上找一个点,使得该点到其他点的最大距离最小. 题解:随便找几个点画个图,不难发现,答案具有凹凸性,有极小值,所以我们直接三分来找即可. 代码: int n; lo ...
- 2016-2017 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2016)
题目链接 Codefores_Gym_101164 Solved 6/11 Penalty Problem A Problem B Problem C Problem D Problem E Pr ...
- 2017-2018 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2017)
A. Cakey McCakeFace 按题意模拟即可. #include<stdio.h> #include<iostream> #include<string.h&g ...
- Southeastern European Regional Programming Contest 2019
easy: I medium-easy: BDEGJ medium: F medium-hard: A A. B. 按 x 排序,\(dp[i][j][k]\) 表示考虑前 \(i\) 个物品,lev ...
- ACM ICPC, Damascus University Collegiate Programming Contest(2018) Solution
A:Martadella Stikes Again 水. #include <bits/stdc++.h> using namespace std; #define ll long lon ...
- 2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
A. Within Arm's Reach 留坑. B. Bribing Eve 枚举经过$1$号点的所有直线,统计直线右侧的点数,旋转卡壳即可. 时间复杂度$O(n\log n)$. #includ ...
随机推荐
- redis客户端使用密码
./redis-cli -h 127.0.0.1 -p 6379 -a password
- 【RF库Collections库测试】关键字append to list
Arguments:[ list_ | *values ]Adds `values` to the end of `list`.
- 怎么下载tomcat的其他版本
下载地址: http://archive.apache.org/dist/tomcat/ 里面包含tomcat的各个版本,windows版本.linux版本,tomcat7.0.x等.
- PHP webservice 接口实例
原文地址,就不摘抄了 http://www.sky00.com/archives/91.html
- 微信公众号支付JSAPI,提示:2支付缺少参数:appId
因为demo中支付金额是定死的,所以需要调整. 所以在使用的JS上添加了参数传入.这里的传入string类型的参数,直接使用是错误的,对于方法,会出现appid缺少参数的错误 //调用微信JS api ...
- UVa 130 - Roman Roulette
模拟约瑟夫环 Roman Roulette The historian Flavius Josephus relates how, in the Romano-Jewish conflict o ...
- 在linux下安装wordpress
win下的简直傻瓜式操作:xampp打包一键安装 linux下的考虑到一些权限问题 还是有点蛋疼的 现在把流程贴出来做下记录: linux下安装xampp和wordpress的流程 ×由于linux下 ...
- HTML标签img--改变图片尺寸
转自:https://blog.csdn.net/u012377333/article/details/50508484 1.统一大小? 我的网页上面有许多的图片,有的大,有的小,我想如果图片大的实现 ...
- Thrift Expected protocol id ffffff82 but got 0
如果服务端配的也是noblock=false;客户端不能改成noblock=true;
- ThinkPHP做自动登陆及异位或加密COOKIE!
异位或加密方法: /* *登陆如果自动登陆加密 *默认是0解密状态,1是加密 *采用的方法是异位或加密 */ function encrytion($value,$type=0){ $key = md ...