C
题意:给你 n*m 的字符串矩阵,要求删除最少的列,使得每一行的字典序大于其前面一行。
思路:我们可以从0到n-1依次判断是否需要删除该列。对于某一列,只有当出现了 某个位置小于其前面的位置,并且前面保留的列不能决定其大小,才考虑删掉。可以对每个位置设一个标志,表示这个位置是否已经被“决定了”。
#include<bits/stdc++.h>
#define SPEED_UP iostream::sync_with_stdio(false);
using namespace std;
#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 inf = 0x7fffffff;
const int Maxn = 1005;
int n, m;
char a[105][105];
int flag[105];
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
cin >> n >> m;
rep(i, 0, n-1) cin >> a[i];
int ans = 0;
rep(k, 0, m-1) {
int ok = 1;
rep(i, 1, n-1) {
if (a[i][k] < a[i-1][k]) {
if (flag[i] == 0) {
ok = 0;
break;
}
}
}
if (ok) {
rep(i, 1, n-1)
if (a[i][k] > a[i-1][k]) flag[i] = 1;
}
else
++ans;
}
cout << ans;
return 0;
}
D
题意:题目描述了一个赛制,每局比赛先赢t分的人赢得此局,先赢s局的人赢得整场比赛,现在给出一个序列表示每场比赛的序列,求出所有可行的s与t。
思路:从1到n枚举t即可,对于每个t,可以在最多算n/t次,总的时间复杂度是个和谐函数。
#include<bits/stdc++.h>
#define SPEED_UP iostream::sync_with_stdio(false);
using namespace std;
#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 inf = 0x7fffffff;
const int Maxn = 1005;
int n, m;
char a[105][105];
int flag[105];
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
cin >> n >> m;
rep(i, 0, n-1) cin >> a[i];
int ans = 0;
rep(k, 0, m-1) {
int ok = 1;
rep(i, 1, n-1) {
if (a[i][k] < a[i-1][k]) {
if (flag[i] == 0) {
ok = 0;
break;
}
}
}
if (ok) {
rep(i, 1, n-1)
if (a[i][k] > a[i-1][k]) flag[i] = 1;
}
else
++ans;
}
cout << ans;
return 0;
}
E
题意:有n个part,m个actor。每个part两个属性(ai, bi),每个actor(ci,di,ki)。一个part可以分配给一个actor,IFF ci <= ai <= bi <= di,ki是一个actor最多可以得到的part数。求所有的part是否都可以被分配给actor。
思路:将part和actor一起先根据两元组排序(actor不看ki),先按照第一个元素排,第一个元素相同的actor在前,part在后。然后建一个set,根据排序顺序依次扫描,如果是actor,加入set,如果是part,在set中以bi为lowerbound寻找actor。。就这么一个贪心 Orz。。。
#include<bits/stdc++.h>
#define SPEED_UP iostream::sync_with_stdio(false);
using namespace std;
#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;
typedef pair<int, int> pi;
const int Maxn = (int)1e5+10;
int ai[Maxn], bi[Maxn], ci[Maxn], di[Maxn], ki[Maxn];
struct Node {
int idx;
int type;
void GetInterval(int& l, int& r) const {
if (type == 0) {
l = ai[idx];
r = bi[idx];
} else {
l = ci[idx];
r = di[idx];
}
}
};
struct comp {
bool operator () (const Node& lhs, const Node& rhs) const {
int l1, l2, r1, r2;
lhs.GetInterval(l1, r1);
rhs.GetInterval(l2, r2);
if (l1 == l2) {
if (lhs.type == 0 && rhs.type == 1)
return false;
else
return true;
}
else
return l1 < l2;
}
} Comp;
struct classcomp {
bool operator () (const Node& lhs, const Node& rhs) const {
int l1, l2, r1, r2;
lhs.GetInterval(l1, r1);
rhs.GetInterval(l2, r2);
return r1 < r2;
}
};
int ans[Maxn];
int n, m;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
SPEED_UP
vector<Node> arr;
cin >> n;
rep(i, 1, n) {
cin >> ai[i] >> bi[i];
arr.push_back((Node){i, 0});
}
cin >> m;
rep(i, 1, m) {
cin >> ci[i] >> di[i] >> ki[i];
arr.push_back((Node){i, 1});
}
/*
if (n == 500 && ai[1] == 1 && bi[1] == 1) {
cout << m << endl;
rep(i, 1, m) cout << ci[i] << ' ' << di[i] << ' ' << ki[i] << endl;
return 0;
}
*/
//cout << "hello" << endl;
stable_sort(arr.begin(), arr.end(), Comp);
//cout << "hello" << endl;
multiset<Node, classcomp> s;
int nSize = arr.size();
int ok = 1;
#ifndef ONLINE_JUDGE
rep(i, 0, nSize-1) cout << "(" << arr[i].idx << "," << arr[i].type << ")" << ' ';cout << endl;
#endif
rep(i, 0, nSize-1) {
if (arr[i].type == 0) {
auto it = s.lower_bound(arr[i]);
if (it == s.end()) {
//cout << "break at idx: " << arr[i].idx << endl;
ok = 0;
break;
} else {
//cout << "give part " << arr[i].idx << " to " << it->idx << endl;
ans[arr[i].idx] = it->idx;
if ((--ki[it->idx]) == 0) s.erase(it);
}
} else {
s.insert(arr[i]);
}
//cout << "set size: " << s.size() << endl;
}
if (ok) {
cout << "YES\n";
rep(i, 1, n-1) cout << ans[i] << ' ';cout << ans[n] << endl;
}
else
cout << "NO\n";
return 0;
}