Problem - B - Martian Sunrise贪心
题目描述:
给你行音调,每行音调有个元素,给你一行目标音调 , 每次可以从行任选两行,作为你的元素集合去匹配目标音调,求最少多少次完成匹配。
题目分析:
所有选择的方案总共,乘上总元素大约,然后直接从第一个目标音调的元素枚举到,同时枚举所有现存的包含当前元素的集合,同时去除不包含的,如何此时没有任何一个集合满足,则重新枚举所有集合并且答案数。这里有个贪心正确性:取匹配目标元素最长的集合并不会让总集合数变多。时间复杂度大约左右。
题目代码:
map<string, int> mp;
int cnt;
set<int> b[300];
bool st[300];
void solve()
{
int m;
cin >> m;
vector<int> v[m];
for (int i = 0; i < m; i++)
{
for (int j = 0; j < 7; j++)
{
string s;
cin >> s;
if (!mp[s])
mp[s] = ++cnt;
v[i].pb(mp[s]);
}
}
int n;
cin >> n;
vector<int> a(n);
for (auto &x : a)
{
string s;
cin >> s;
x = mp[s];
}
int idx = 0;
if (m == 1)
{
for (auto &x : v[0])
b[idx].insert(x);
idx++;
}
for (int i = 0; i < m; i++)
{
for (int j = i + 1; j < m; j++)
{
for (auto &x : v[i])
b[idx].insert(x);
for (auto &x : v[j])
b[idx].insert(x);
idx++;
}
}
memset(st, 0, sizeof st);
int num = idx, ans = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < idx; j++)
{
if (!st[j] && b[j].find(a[i]) == b[j].end())
num--, st[j] = 1;
if (!num)
{
i--;
break;
}
}
if (!num)
num = idx, ans++, memset(st, 0, sizeof st);
}
cout << ans << "\n";
}
Problem - I. Lazy Painting/DFS/SET(stl)
题目描述:
实验室地板可以表示为一个 行、 列的矩阵,总共有 块瓷砖。指令是以矩形区域为单位进行涂漆,每个矩形的高度为 ,宽度为 ,且这些矩形可以重叠。每次指令后,需要计算还有多少瓷砖未涂漆。
马加里达负责执行指令,她会检查矩形的左边界,如果左侧边框中的瓷砖都已经涂漆,她会跳过该矩形。如果有未涂漆的瓷砖,她会将从左侧边框可到达的所有未涂漆的瓷砖进行涂漆。如果只有矩形内的未涂漆瓷砖可以到达某个瓷砖,那么这个瓷砖也会被涂漆。
输入
第一行包含五个整数 、 和 、、 , 和 . 然后是 行. 第 行包含两个整数 和 , —要绘制的矩形区域的左上平铺. 研究实验室最左边最上面的瓦片是 .
输出
每次指令过后有多少未覆盖的瓷片.
题目分析:
因为是检查左边界,用记录每列还有哪些没有被覆盖。当执行命令的时候二分查找还存在的,加到队列中进行覆盖即可,同时维护答案–。因为整个询问 次的时候,矩阵只会被访问一次 ,每次访问的时候set删除 ,所以总复杂度约为 .
题目代码:
int n, m, h, w, Q, ans, dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
set<int> s[N];
queue<PII> q;
bitset<M> st;
void bfs(int u, int v)
{
int nn = u + h - 1, mm = v + w - 1;
set<int>::iterator it = s[v].lower_bound(u);
// cout<<u<<" "<<*it<<" "<<nn<<" "<<mm<<"\n";
while (*it <= nn)
{
q.push({*it, v});
// cout<<*it<<"\n";
st[(*it - 1) * m + v] = 1;
it++, ans--;
}
// cout<<nn<<"#"<<mm<<"#"<<q.size()<<"\n";
while (q.size())
{
auto [xx, yy] = q.front();
q.pop();
s[yy].erase(xx);
for (int i = 0; i < 4; i++)
{
int t = xx + dx[i];
int z = yy + dy[i];
if (t >= u && t <= nn && z >= v && z <= mm && st[(t - 1) * m + z] == 0)
{
st[(t - 1) * m + z] = 1;
q.push({t, z});
ans--;
}
}
}
}
void solve()
{
cin >> n >> m >> h >> w >> Q;
ans = n * m;
for (int i = 1; i <= n+1; i++)
{
for (int j = 1; j <= m; j++)
s[j].insert(i);
}
while (Q--)
{
int x, y;
cin >> x >> y;
bfs(x, y);
cout << ans << "\n";
}
}