您的位置:首页 > 编程语言 > Go语言

codeforces goodbye2014

2015-01-01 00:30 232 查看
B

题意:给一个n排列, 和一个nxn矩阵,矩阵中元素代表那些位置上的元素可以互相交换,要搞出字典序最小的排列。。

思路:floyd一遍,然后位置从小到大,将能放在该位上最小的元素与该位置上现在的元素交换,,如果两个位置之间存在一条路径,是可以进行一系列交换使得最后等效于他们直接交换。。一开始没想到,用了个vis禁掉已经换过的位置,然后模拟交换过程。。。直接FST。。

#include<bits/stdc++.h>
using namespace std;

#define SPEED_UP iostream::sync_with_stdio(false);
#define FIXED_FLOAT cout.setf(ios::fixed, ios::floatfield);
#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))

typedef long long LL;

const int Maxn = 300;

int n;

int p[Maxn+5];
int d[Maxn+5][Maxn+5];

char buf[1000];

bool cmp(int lhs, int rhs) {
return p[lhs] < p[rhs];
}

int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
cin >> n;
rep(i, 1, n) {
cin >> p[i];
}
rep(i, 1, n) {
cin >> buf;
rep(j, 1, n)
d[i][j] = buf[j-1]-'0';
}
rep(i, 1, n) d[i][i] = 1;
rep(k, 1, n)
rep(i, 1, n)
rep(j, 1, n)
if (i!=j)
d[i][j] |= d[i][k]&d[k][j];

rep(r, 1, n) {
int pos = r, _min = p[r];
rep(i, r+1, n)
if (d[r][i] && p[i] < _min) {
pos = i;
_min = p[i];
}
swap(p[r], p[pos]);
}
rep(i, 1, n-1) cout << p[i] << ' ';cout << p
;
return 0;
}
C

题意:略。。。

思路:

初始顺序,第一个放的一定是第一次出现的元素。假设存在一个最优序列,第一个元素不是第一次出现的元素,那个可以把第一次出现的元素拿到顶上,这个新的序列显然优于刚才的序列。沿用这个思路,我们可以证明最优序列元素的顺序恰好是按照第一次访问顺序来的。。

#include<bits/stdc++.h>
using namespace std;

#define SPEED_UP iostream::sync_with_stdio(false);
#define FIXED_FLOAT cout.setf(ios::fixed, ios::floatfield);
#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))
#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))

typedef long long LL;

const int Maxn = 1005;

int w[Maxn], d[Maxn], p[Maxn], vis[Maxn];
int n, m;

int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
cin >> n >> m;
rep(i, 1, n) cin >> w[i];
rep(i, 1, m) cin >> d[i];
int idx = 1;
memset(vis, 0, sizeof(vis));
rep(i, 1, m)
if (!vis[d[i]]) {
vis[d[i]] = 1;
p[idx++] = d[i];
}
list<int> li;
long long ans = 0;
rep(i, 1, n) li.push_back(p[i]);
rep(i, 1, m) {
int aim = d[i];
for (list<int>::iterator it=li.begin();it!=li.end();++it) {
if (*it != aim) {
ans += w[*it];
}
else {
li.erase(it);
li.insert(li.begin(), aim);
break;
}
}
}
cout << ans;
//rep(i, 1, n) cout << p[i] << ' ';cout << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: