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. Go丨语言学习笔记--switch

    Java语言与Go语言的switch对比 Go语言 switch str { case "yes" : do something ... case "no" d ...

  2. 从CWnd::GetSafeHwnd实现得到的知识

    在看MFC源码的过程中,有个地方一直不解,看如下代码 BOOL CFrameWnd::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWO ...

  3. robotium 测试APK<一> 建立测试工程

    1.准备Android开发环境 2.准备签名工具http://www.troido.de/re-sign.jar 1.建立测试工程 打开Eclipse,点击File->New一个Android ...

  4. JavaScript的中类型转换

    JavaScript的类型转换 By 大志若愚  (一)转换为字符串 X + '' toString() String() 函数转换为字符串一般是将函数体输出,不过可以重写其toString方法  ( ...

  5. 微信开放平台搭建之EasyWeChat

    背景 公司有一个产品,需要用到微信授权登录及微信消息推送等功能.本来能够简单的使用公众号的接口将appid和appsecrect等信息写到配置文件里,但是作为一个产品化的东西,从体验等各方面来讲都不能 ...

  6. bootstrap 全局样式

    reset.css html { font-family: sans-serif; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100% ...

  7. win7-64 mysql的安装

    1.https://jingyan.baidu.com/article/597035521d5de28fc00740e6.html 2.net start mysql 无法启动的3534的错误的解决办 ...

  8. 手把手教你上传文件到GitHub并发布到pod

    第一步:定位到要上传到GitHub的文件夹, 第二步:GitHub中建立一个仓库,用于存放项目. 第三步:建立podspec文件, pod spec create openinstall 然后修改里面 ...

  9. [poj3417]Network(LCA+树形dp)

    题意:给出一棵无根树,然后下面再给出m条边,把这m条边连上,每次你去两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 解题关键:边权转化为点权,记录每条边被环覆盖的次数,通过val[a] ...

  10. ubuntu系统开root以及(su:认证失败)完美解决

    开机进入桌面,ctrl+alt+T打开终端————在此时终端显示的是 用户名@电脑名:-$   表示普通用户 在此处输入:sudo passwd root 此时提示———— [sudo] passwo ...