- 题目:
给你n组,每组都有两个数字A[i],B[i],让你从n组里面选择三组,这三组里面不能有其中两组的A[i]相同并且其中的两组B[i]相同,问你有多少种选择方案 - 思路:
先求出所有的方案数 就是组合数,然后减去相同的两组条件,就是答案,这是一个数学题,需要推一下,
代码:
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl '\n'
#define all(x) x.begin(),x.end()
#define pb push_back
#define PII pair<int,int>
#define int long long
#define ios ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
const int N = 2e5 + 100,mod = 1e9 + 7;
PII a[N];
map<int,int> mp,mp2;
void solve()
{
int n; cin >> n;
for(int i = 1;i <= n;i ++ )
cin >> a[i].fi >> a[i].se;
sort(a + 1,a + 1 + n);
mp.clear();mp2.clear();
for(int i = 1;i <= n;i ++ )
{
mp[a[i].se]++;
mp2[a[i].fi]++;
}
int ans = 0;
for(int i = 1;i <= n;i ++ )
{
ans += (mp[a[i].se] - 1) * (mp2[a[i].fi] - 1);
}
int y = (n - 2) * (n - 1) * n / 6;
cout << y - ans << endl;
}
signed main()
{
ios;int T; cin >> T;
while(T -- ) solve();
return 0;
}
- 题目:
就是有两种人,一种是诚实人,一种是骗子,骗子只说假话,诚实人只说真话,给你数字a,b,和字符串S,表明a说b是什么人,S = “imposter” 表明是骗子,反之为诚实人,问你如果能符合给的条件下,骗子最多是多少,不符合条件就输出 -1
思路:
这里想到两种方法一种是扩展域并查集一种是dfs染色法,扩展域的话就开两倍的集合,然后用一个size数组来统计骗子的数量,如果是染色法的话,就直接dfs就行,
这个最重要的是如果说是骗子,那a和b一定不是同类,否则一定是同类,然后就直接写就行
代码:
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl '\n'
#define all(x) x.begin(),x.end()
#define pb push_back
#define PII pair<int,int>
#define ios ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
const int N = 1e6,M = N * 2,mod = 1e9 + 7;
int h[M],e[M],w[M],ne[M],idx;
int color[M];
int ans1,ans2;
int res;
void add(int a,int b,int c)
{
e[idx] = b,w[idx] = c,ne[idx] = h[a],h[a] = idx++;
}
void dfs(int u,int c)
{
color[u] = c;
if(c == 0) ans1++;
else ans2++;
for(int i = h[u];i != -1;i = ne[i])
{
int j = e[i];
if(color[j] == -1)
dfs(j,w[i] ^ c);
else
{
if((color[u] ^ color[j]) != w[i])
{
res = -1e9;
}
}
}
}
void solve()
{
int n,m; cin >> n >> m;
idx = 0;
for(int i = 0;i <= n;i ++ )
{
h[i] = -1;
color[i] = -1;
}
for(int i = 1;i <= m;i ++ )
{
int a,b; string s;
cin >> a >> b >> s;
if(s[0] == 'i')
{
add(a,b,1);
add(b,a,1);
}
else
{
add(a,b,0);
add(b,a,0);
}
}
res = 0;
for(int i = 1;i <= n;i ++ )
{
if(color[i] == -1)
{
ans1 = 0,ans2 = 0;
dfs(i,0);
res += max(ans1,ans2);
if(res < 0)
{
cout << "-1" << endl;
return;
}
}
}
cout << res << endl;
}
int main()
{
ios;int T; cin >> T;
while(T -- ) solve();
return 0;
}
#include <bits/stdc++.h>
#define fi first
#define se second
#define endl '\n'
#define all(x) x.begin(),x.end()
#define pb push_back
#define PII pair<int,int>
#define int long long
#define ios ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
using namespace std;
const int N = 4e5 + 100,mod = 1e9 + 7;
bool st[N];
int color[N];
int si[N],p[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int add(int a,int b)
{
a = find(a);
b = find(b);
if(a != b)
{
p[a] = b;
si[b] += si[a];
}
}
void solve()
{
int n,m; cin >> n >> m;
for(int i = 1;i <= n * 2;i ++ )
{
p[i] = i;
if(i <= n)
si[i] = 0;
else
si[i] = 1;
}
int f = 0;
for(int i = 1;i <= m;i ++ )
{
int a,b; string s;
cin >> a >> b >> s;
if(s[0] == 'i')
{
add(a,b + n);
add(a + n,b);
}
else
{
add(a,b);
add(a + n,b + n);
}
}
int res = 0;
for(int i = 1;i <= n;i ++ )
{
int pa = find(i),pb = find(i + n);
if(pa == pb)
{
cout << "-1" << endl;
return;
}
else if(i == pa)
{
res += max(si[pa],si[pb]);
}
}
cout << res << endl;
}
signed main()
{
ios;int T; cin >> T;
while(T -- ) solve();
return 0;
}