http://codeforces.com/gym/101341

其实我觉得这份题很不错的,虽然是div2,但是感觉对我挺有帮助(我比较垃圾0.0),还没补完(做的时候一直蒙逼,要补很多题)先写一点点的题解,后面的以后补上。

A:

B:这题有一个bug就是,当你一个"happiness"都没有的时候,你交换哪一个?如果随机输出的话是有bug的,就是比如你交换1和2,(注意都是要不同的pos),那么我构造ahppiness,就错了,交换后出现就不行了。所以还要自己处理一下。我是找有没有两个相同的字母,有就交换他们,就相当于没变了,没有的话,就不会出现"pp"和"ss",怎么交换都是成立的。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 2e5 + ;
char str[maxn];
char sub[] = "0happiness";
int lensub;
vector<int>pos[];
void work() {
scanf("%s", str + );
int lenstr = strlen(str + );
int beOne = , enOne = , beTwo = , enTwo = ;
char ch[] = {};
for (int i = ; i <= lenstr; ++i) {
for (int j = ; j <= ; ++j) ch[j] = ch[j + ];
ch[] = str[i];
pos[str[i]].push_back(i);
if (strcmp(ch + , sub + ) == ) {
if (beOne == ) {
beOne = i - ; enOne = i;
continue;
}
if (beTwo == ) {
beTwo = i - ; enTwo = i;
continue;
}
printf("NO\n");
return;
}
}
// printf("%d %d %d %d\n", beOne, enOne, beTwo, enTwo);
printf("YES\n");
if (!beOne && !beTwo) {
for (int i = 'a'; i <= 'z'; ++i) {
if (pos[i].size() >= ) {
printf("%d %d\n", pos[i][], pos[i][]);
return;
}
}
printf("1 %d\n", lenstr);
return;
}
if (!beTwo) beTwo = ;
while (str[beTwo] == str[beOne]) beTwo++;
printf("%d %d\n", beOne, beTwo);
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
lensub = strlen(sub + );
work();
return ;
}

C:推公式貌似有点难度,做的时候一直想着推公式,分类讨论太乱了。然后吃了个饭回来想到可以二分答案。二分答案val,判定条件是:首先对于每一种求,最多只能拿Min(val, a + c)个,然后判断其是否> n,

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
LL a, b, c, n, m;
bool check(LL val) {
LL ra = min(val, a + c);
LL rb = min(val, b + c);
return ra <= n && rb <= m;
}
void work() {
cin >> a >> b >> c >> n >> m;
LL be = , en = a + b + c;
// cout << check(3) << endl;
while (be <= en) {
LL mid = (be + en) >> ;
if (check(mid)) be = mid + ;
else en = mid - ;
}
cout << en << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

D:签到题,对于一个数,可以向左跳或者向右跳,相当于可以加,可以减。回顾ax + by = c是否有整数解,只需要gcd(a, b) | c

这是扩展欧几里德的内容,现在扩展到n个,一样的gcd即可。(比赛的时候还卡了这题,哭)

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
map<int, bool>vis, ans;
const int maxn = + ;
int a[maxn], n;
const int low = -1e9, high = 1e9;
int x; void work() {
scanf("%d%d", &n, &x);
scanf("%d", a + );
int gg = a[];
for (int i = ; i <= n; ++i) {
scanf("%d", a + i);
gg = __gcd(gg, a[i]);
}
if (x % gg == ) printf("YES\n");
else printf("NO\n");
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

E:这题我写得很复杂,也没看懂别人如何贪心,我是直接化公式,然后暴力segment tree维护。思路是,他从t1开始,首先把它左边的点都暴力走过去,因为没有其他方法了,然后,就是在[t1, t2]这段路上,选一个点(可能不选),走过去,然后走回t1传送去t2,然后从t2走去左边剩下的点,再走回来。一共花费的时间是,假如[t1, t2]这里有两个点pos[1], pos[2],那么花费的时间是,(pos[1] - t1) * 2 + (t2 - pos[2]) * 2 = 2 * (t2 - t1) + 2 * (pos[1] - pos[2]),所以应该选一个pos[i] - pos[i + 1]最小的去走,线段树维护。很复杂啦写的,

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = + ;
#define root 1, m, 1
#define lson L, mid, cur << 1
#define rson mid + 1, R, cur << 1 | 1
LL a[maxn], b[maxn];
LL dis[maxn];
LL mi[maxn << ];
void pushUp(int cur) {
mi[cur] = min(mi[cur << ], mi[cur << | ]);
}
void build(int L, int R, int cur) {
if (L == R) {
mi[cur] = dis[L];
return;
}
int mid = (L + R) >> ;
build(lson);
build(rson);
pushUp(cur);
}
LL ask(int be, int en, int L, int R, int cur) {
if (be > en) return inf + inf;
if (L >= be && R <= en) {
return mi[cur];
}
int mid = (L + R) >> ;
LL ans = inf + inf;
if (be <= mid) {
ans = ask(be, en, lson);
}
if (en > mid) {
ans = min(ans, ask(be, en, rson));
}
return ans;
}
void work() {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) cin >> a[i];
for (int i = ; i <= m; ++i) {
cin >> b[i];
if (i > ) {
dis[i - ] = b[i - ] - b[i];
}
}
dis[m] = inf + inf;
build(root);
a[n + ] = inf;
LL sumTime = ;
int pb = , pa = ;
if (b[pb] <= a[]) {
sumTime += * (a[] - b[pb]);
}
while (pb <= m && b[pb] <= a[]) pb++;
while (pb <= m) {
if (pa == n) {
sumTime += (b[m] - a[pa]) * ;
break;
}
if (a[pa + ] <= b[pb]) {
pa++;
continue;
}
LL res1 = a[pa + ] - a[pa];
res1 = min(res1, (a[pa + ] - b[pb]) * );
if (b[pb + ] <= a[pa + ]) {
res1 = min(res1, (b[pb] - a[pa]) * + (a[pa + ] - b[pb + ]) * );
} else res1 = min(res1, (b[pb] - a[pa]) * );
int pos1 = lower_bound(b + , b + + m, a[pa]) - b;
int pos2 = upper_bound(b + , b + + m, a[pa + ]) - b;
res1 = min(res1, (b[pos2 - ] - a[pa]) * );
pos2 -= ;
// cout << dis[2] << endl;
// cout << ask(pos1, pos2, root) << endl;
LL res3 = * ask(pos1, pos2, root) + * (a[pa + ] - a[pa]);
// cout << res3 << endl;
sumTime += min(res1, res3);
pa++;
while (pb <= m && b[pb] <= a[pa]) pb++;
}
cout << sumTime << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

F:

G:倒序模拟,一开始找1所在的位置pos, 设1喜欢的人是y[pos],然后就相当于找y[pos]那个人的名字,也是倒序模拟,直到找不到了,就直接输出那个人的名字就ok

H:能证明的是,首先找到一个最大的数字val,在row,col中,这个数字是必定删除的,然后试试删除row,或者删除col,4种情况试一试就好。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
typedef pair<int, int> pii;
const int maxn = 1e3 + ;
int a[maxn][maxn];
int n, m;
pii findMax(int delRow, int delCol) {
int mx = -, row = -, col = -;
for (int i = ; i <= n; ++i) {
if (i == delRow) continue;
for (int j = ; j <= m; ++j) {
if (j == delCol) continue;
if (mx < a[i][j]) {
mx = a[i][j];
row = i;
col = j;
}
}
}
return make_pair(row, col);
}
vector< pair<pii, int> >vc;
int ansMx = inf;
void dfs(int row, int col, int delRow, int delCol) {
pii res = findMax(delRow, delCol);
if (!row && !col) {
vc.push_back(make_pair(make_pair(delRow, delCol), a[res.first][res.second]));
if (ansMx > a[res.first][res.second]) {
ansMx = a[res.first][res.second];
}
return;
}
if (row) {
dfs(row - , col, res.first, delCol);
}
if (col) {
dfs(row, col - , delRow, res.second);
}
}
void work() {
cin >> n >> m;
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
cin >> a[i][j];
}
}
dfs(, , , );
for (int i = ; i < vc.size(); ++i) {
if (vc[i].second == ansMx) {
cout << vc[i].first.first << " " << vc[i].first.second << endl;
return;
}
}
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
IOS;
work();
return ;
}

I:这是一题神奇的题,其实这个东西我应该算学过,但是它换去矩阵了,所以就转不过来,思路是随机生成一个矩阵[1 X n]的矩阵,那么有rand * a * b = rand * c,这些复杂度才O(n^2),多随机几个,概率就满足了。这有点像那些米勒测试啊。

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e3 + ;
struct Matrix {
int a[maxn][maxn];
int row;
int col;
bool operator != (struct Matrix& rhs) const {
for (int i = ; i <= col; ++i) {
if (a[][i] != rhs.a[][i]) return true;
}
return false;
}
}ans[], c, cmp;
struct Matrix matrix_mul(struct Matrix a, struct Matrix b, int MOD) { //求解矩阵a*b%MOD
// struct Matrix c = {0}; //这个要多次用到,栈分配问题,maxn不能开太大,
//LL的时候更加是,空间是maxn*maxn的,这样时间用得很多,4和5相差300ms
c.row = a.row; //行等于第一个矩阵的行
c.col = b.col; //列等于第二个矩阵的列
for (int i = ; i <= c.row; ++i) for (int j = ; j <= c.col; ++j) c.a[i][j] = ;
for (register int i = ; i <= a.row; ++i) {
for (register int k = ; k <= a.col; ++k) {
if (a.a[i][k]) { //应付稀疏矩阵,0就不用枚举下面了
for (register int j = ; j <= b.col; ++j) {
c.a[i][j] = (c.a[i][j] + 1LL * a.a[i][k] * b.a[k][j]) % MOD;
}
}
}
}
return c;
}
void work() {
srand((time(NULL)));
int n;
scanf("%d", &n);
for (int i = ; i <= ; ++i) {
ans[i].row = ans[i].col = n;
for (int j = ; j <= n; ++j) {
for (int k = ; k <= n; ++k) {
scanf("%d", &ans[i].a[j][k]);
}
}
}
cmp.row = , cmp.col = n;
// cout << RAND_MAX << endl;
for (int i = ; i <= ; ++i) {
int upDate = rand();
for (int k = ; k <= n; ++k) {
cmp.a[][k] = rand() % + upDate;
}
Matrix res1 = matrix_mul(cmp, ans[], 1e9 + );
res1 = matrix_mul(res1, ans[], 1e9 + );
Matrix res2 = matrix_mul(cmp, ans[], 1e9 + );
if (res1 != res2) {
printf("NO\n");
return;
}
}
printf("YES\n");
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
work();
return ;
}

666

J:

K:

L:

M:签到题,模拟即可。一个人优先杀最后那个。

X Samara Regional Intercollegiate Programming Contest DIV2的更多相关文章

  1. Gym100971B Gym100971C Gym100971F Gym100971G Gym100971K Gym100971L(都是好写的题。。。) IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13, 2016

    昨天训练打的Gym,今天写题解. Gym100971B 这个题就是输出的时候有点小问题,其他的都很简单. 总之,emnnn,简单题. 代码: #include<iostream> #inc ...

  2. 2017, X Samara Regional Intercollegiate Programming Contest 题解

    [题目链接] A - Streets of Working Lanterns - 2 首先将每一个括号匹配串进行一次缩减,即串内能匹配掉的就匹配掉,每个串会变成连续的$y$个右括号+连续$z$个左括号 ...

  3. IX Samara Regional Intercollegiate Programming Contest F 三分

    F. Two Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  4. Codeforces Gym100971 L.Chess Match (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    这个题就是两个队,看最多能赢的个数,然后比较一下,看两个队是都能赢彼此,还是只有一个队赢的可能性最大.表达能力不好,意思差不多... 和田忌赛马有点像,emnnn,嗯. 代码: 1 #include& ...

  5. Codeforces Gym100971 K.Palindromization-回文串 (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    这个题就是从字符串中删除一个字符,然后剩下的是回文串. 我写的代码虽然长得好看,但是循环里面的比较条件容易想错,太智障了... 一开始写的是计数比较,但是有的时候下标相同的也比较了,为了简单一些,直接 ...

  6. Codeforces Gym100971 G.Repair-思维题(切矩形板子) (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    这个题就是一块大板子,问你能不能切成两块要求的长宽的两块板子,一开始是按切板子想的,感觉有点麻烦. 直接反过来想,把两块要求的板子拼起来,填成一个大板子,看填出来的这个板子和题目给的板子比较,小于等于 ...

  7. Codeforces Gym100971 F.Two Points (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    这个题直接推公式就可以. 就是解一元二次方程,用高中学的公式,函数开口向上,求最大值为(4ac-b*b)/4a. 这个题推出来一元二次方程,然后将最大值的公式化简一下.公式很好推. 这个题有疑问,in ...

  8. Codeforces Gym100971 C.Triangles-组三角形 (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    这个题就是组三角形,从给出的数组里任选两个和未知的边组三角形. 任意两边之和大于第三边,记住这个就可以了. 代码: 1 #include<cstdio> 2 #include<cst ...

  9. Codeforces Gym100971 B.Derangement (IX Samara Regional Intercollegiate Programming Contest Russia, Samara, March 13)

    昨天训练打的Gym,今天写题解. 这个题就是输出的时候有点小问题,其他的都很简单. 代码: #include<iostream> #include<cstring> #incl ...

随机推荐

  1. listen 77

    Your Dog Wants YOUR Food Does your puppy turn his nose up at his own chow—because he wants some of w ...

  2. kettle脚本定时任务不执行

    问题描述:在centos机器上部署了kettle脚本,每天定时跑一次,但是并没有成功跑,手动执行命令是可以的.而且写了一个测试的shell脚本也是可以执行的. 解决方案: 将2的错误输出,/usr/l ...

  3. POJ2763 Housewife Wind(树剖+线段树)

    After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy lif ...

  4. MySQL当月负毛利订单明细_20161027

    #当月每天负毛利订单明细 SELECT c.ID,a.city AS 城市,a.username AS 用户ID,a.订单日期,a.订单号,a.销售确认额,a.成本额,a.毛利1, CASE THEN ...

  5. ogg概叙、架构、进程

    一. OGG 概述 OGG 全称Oracle Golden Gate. 历史: Golden Gate公司于1995年成立于美国加州旧金山,它的名称源自旧金山闻名于世的金门大桥.两位创始人Eric F ...

  6. poj1325机器工作——二分图最小点覆盖

    题目:http://poj.org/problem?id=1325 二分图求最大匹配,即为最小点覆盖: 一开始我写得较麻烦,求出最大匹配又去搜增广路,打标记求最小点覆盖: 然而两种方法都没写“ans= ...

  7. Ubuntu 获得超级用户权限

    sudo passwd root 首先要先输入当前用户的密码,再在"输入新的UNIX密码"后面输入你想要设置的 root 密码即可,然后就可以切换到 super user 了: $ ...

  8. 创建oracle数据库图示(一步一步教你安装oracle)

    123456 密码 版权声明:本文为博主原创文章,未经博主允许不得转载.

  9. 使用API修改控制台输出的颜色(前景色和背景色)

    1.api原型 SetConsoleTextAttribute BOOL WINAPI SetConsoleTextAttribute( _In_ HANDLE hConsoleOutput, // ...

  10. POJ 1064 Cable master (二分)

    题意:给定 n 条绳子,它们的长度分别为 ai,现在要从这些绳子中切出 m 条长度相同的绳子,求最长是多少. 析:其中就是一个二分的水题,但是有一个坑,那么就是最后输出不能四舍五入,只能向下取整. 代 ...