hdu-6794 Tokitsukaze and Multiple
题意:给n个数和一个模数p,现在需要你对这n个数中的若干个连续的数进行合并,最后要使得这个序列中尽可能多的数能够被p整除,输出最大个数
思路:如果这个数本身就是p,那么我们就不需要让它跟其他数进行合并,因为再怎么合并还是算1个,划不来。然后就是其他的数了,我们对不是p的数进行求前缀和并且取模,如果前缀和相同的话那么就是出现了可以被p整除的组合。
比如说一个序列 1 4 2 ;p 为 3,这个序列的前缀和就是 1 2 1,那么就可以知道第二项和第三项是可以组成能够整除3的数的,这个需要用vis数组来存一下前面出现过的数就可以了。还有需要注意的一点就是当一个方案产生的时候,vis数组需要清空,因为必须是连续的数才可以合并。
#include <bits/stdc++.h>
using namespace std;
int _, n, p, a, sum[100005];
map <int, bool> vis;
int main() {
scanf("%d", &_);
while(_--) {
vis.clear();
int ans = 0;
scanf("%d %d", &n, &p);
for(int i = 1;i <= n; i++) {
scanf("%d", &a); a %= p;
if(a == 0) {
vis.clear();
sum[i] = 0;
ans++;
continue;
}
sum[i] = (sum[i-1]+a)%p;
if(vis[sum[i]] || sum[i] == 0) {
ans++;
vis.clear();
sum[i] = 0;
}
else vis[sum[i]] = 1;
}
printf("%d\n", ans);
}
}
hdu-6795 Little W and Contest
题意:给n个人,每个人的能力值要么是1,要么是2,现在选三个人组队,要求就是
1、团队实力之和 ≥ 5
2、团队之间的人互不熟悉
会有n-1次的两两人之间的介绍,介绍之后两人就会变得熟悉,并且与这两个人熟悉的人也都会互相熟悉。现在需要输出 [ 0 , n − 1 ] [0,n-1] [0,n−1] 次介绍之后可以组队的方案数。
思路:最开始互不认识的方案数我们是很好求出来的,然后我们可以考虑两个群体合并之后会对答案产生什么影响。假如x集合与y集合合并,是不是就是影响了从x里面拿一个人,并且从y里面拿出一个人,再从出了这两个集合外拿出一个人的情况,然后我们把能力值不小于5这个因素考虑进来就有以下四种情况可以从原答案中减去。用并查集来维护集合的关系。
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int _, n, x, u, v, fa[100005];
struct node {
long long one;
long long two;
long long tot;
} acm[100005];
long long fac[100005];
long long qpow(long long x, long long n) {
long long res = 1;
for (; n; n >>= 1, x = x * x % mod)
if (n & 1) res = res * x % mod;
return res;
}
long long inv(long long a) {
return qpow(a, mod-2)%mod;
}
void solve() {
fac[0] = 1;
for(int i = 1;i <= 100005; i++) {
fac[i] = (fac[i-1]*i)%mod;
}
}
long long comb(long long n, long long k) {
if(k > n) return 0;
if(k == 1) return n;
return (fac[n]*inv(fac[k])%mod * inv(fac[n-k])%mod);
}
int find(int x) {
if(fa[x] == x) return x;
else return fa[x] = find(fa[x]);
}
int main() {
solve();
scanf("%d", &_);
while(_--) {
long long num1 = 0, num2 = 0;
scanf("%d", &n);
for(int i = 1;i <= n; i++) fa[i] = i;
for(int i = 1;i <= n; i++) {
scanf("%d", &x);
node t;
if(x == 1) {
t.one = 1; t.two = 0;
num1++;
}
if(x == 2) {
t.one = 0; t.two = 1;
num2++;
}
t.tot = t.one + t.two;
acm[i] = t;
}
long long ans = ((comb(num2, 2)*comb(num1, 1))%mod+comb(num2, 3))%mod;
long long res = 0;
printf("%lld\n", ans);
for(int i = 0;i < n-1; i++) {
scanf("%d %d", &u, &v);
int x = find(u), y = find(v);
if(x == y) continue;
long long one1 = acm[x].one, one2 = acm[y].one, two1 = acm[x].two, two2 = acm[y].two;
res = (res+ comb(two1, 1) * comb(two2, 1)%mod * comb(num2-two1-two2, 1))%mod;
res = (res+ comb(two1, 1) * comb(two2, 1)%mod * comb(num1-one1-one2, 1))%mod;
res = (res+ comb(two1, 1) * comb(one2, 1)%mod * comb(num2-two1-two2, 1))%mod;
res = (res+ comb(one1, 1) * comb(two2, 1)%mod * comb(num2-two1-two2, 1))%mod;
acm[y].one += acm[x].one;
acm[y].two += acm[x].two;
acm[y].tot = acm[y].one + acm[y].two;
fa[x] = y;
printf("%lld\n", (ans-res+mod)%mod);
}
}
}
hdu-6799 Parentheses Matching
题意:给一个只含有 “(”, “)”, “*” 的字符串现在你需要进行一下操作将这个字符串变得符合以下要求:
括号互相匹配
长度最短
字典序最小
操作为
* -> (
* -> )
* -> 空气
最后输出修改后的字符串
思路:需要保证字符串最短的情况下字典序最小,就不需要考虑在括号已经匹配的情况下将 ∗ * ∗ 变成括号的情况了,那么我们可以用栈来维护这个括号序列,如果为 ‘)’ ,并且栈不为空那么就形成一个匹配,栈弹出即可。如果栈为空的话证明‘)’是不匹配的,这时候需要一个容器q来装 ∗ * ∗ 的位置,如果q不为空,那么证明这个前面有 ∗ * ∗ ,就把q的最前面(保证字典序)的 ∗ * ∗替换成’(’ 就可以匹配了,如果q仍然为空,那么就不可能满足要求;如果是’(’,直接压入栈,如果是 ∗ * ∗,就直接加入q。
之后就看栈中有多少个’(’ ,然后从q中最后面的 ∗ * ∗看(保证字典序),如果这个 ∗ * ∗的位置在括号后面,那么就可以进行匹配,否则就无法满足要求。
#include <bits/stdc++.h>
using namespace std;
int _;
char s[100007];
deque <int> q;
stack <int> sta;
int main() {
scanf("%d", &_);
while(_--) {
while(!q.empty()) q.pop_back();
while(!sta.empty()) sta.pop();
scanf("%s", s);
bool ok = 1;
int len = strlen(s);
for(int i = 0;i < len; i++) {
if(s[i] == '(') sta.push(i);
else if(s[i] == ')') {
if(!sta.empty()) {
sta.pop();
}
else if(!q.empty()) {
s[q.front()] = '(';
q.pop_front();
}
else {
ok = 0;
break;
}
}
else {
q.push_back(i);
}
}
while(!sta.empty()) {
if(!q.empty() && q.back() > sta.top()) {
s[q.back()] = ')';
sta.pop();
q.pop_back();
}
else {
ok = 0;
break;
}
}
if(ok) {
for(int i = 0;i < len; i++) {
if(s[i] != '*') printf("%c", s[i]);
}
puts("");
}
else puts("No solution!");
}
}