Party
题意:n个成员,其中有m对朋友,现要要求邀请他们参加Party,这个聚会要求吃蛋糕的数量必须是偶数(只有是一对朋友才能吃一个蛋糕)。每个成员有个不开心值,如果不被邀请就会不开心。求满足要求的最小的不开心值。
思路:图论。n个成员就是n个点,m对朋友就是m条边。点1~n,用数组记录每个顶点的度。判断m 的奇偶性,如果是偶数就是全邀请,不开心值为0.如果是奇数就枚举边,如果边是奇数就不邀请该点,如果是偶数就必须不邀请两个相连的两个顶点。取其中的最小不开心值。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 50;
int a[maxn];
int main()
{
int t;
cin >> t;
while(t--)
{
int n,m;
cin >> n >> m;
vector<int> u(m),v(m),b(n+1,0);//u左端点,v右端点 b表示每个端点的度。
for(int i = 1;i <= n;i++) cin >> a[i];
for(int i = 0;i < m;i++)
{
cin >> u[i] >> v[i];
b[u[i]]++;
b[v[i]]++;
}
if(m % 2 == 0) cout << 0 <<endl;//全邀请
else
{
int ans = 0x3f3f3f3f;
for(int i = 0;i < m;i++)
{
int l = u[i],r = v[i];//左右端点
if(b[l] % 2 == 0 && b[r] % 2 == 0)//两个相连的点的度为偶数时
{
ans = min(ans,a[l] + a[r]);
}
if(b[l] % 2) ans = min(ans,a[l]);
if(b[r] % 2) ans = min(ans,a[r]);
}
cout << ans << endl;
}
}
return 0;
}
C.Color the Picture
题意:给一个n行m列的矩阵,k 种颜色,接下来k个数据表示每个颜色能涂多少格。该矩阵是环形的,就是第一行和最后一行是相连的,第一列和最后一列是相连的。要满足每个颜色的上下左右都是同一种颜色。如果这k种颜色可以满足涂满该矩阵就输出”YES”否则输出“NO”。
思路:如果要满足该涂颜料规则一个颜色至少涂两行或两列。有两种涂法按行涂和按列涂。求出一种颜料最多涂几行和k种颜料一共可以涂几行如果n是偶数只需要每种颜色能涂>=2和一共能涂行数>=n即可。如果为奇数就需要有至少有一种颜料多贡献一行。按列涂和按行涂方法一样。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int t;
cin >> t;
while(t--)
{
ll n,m,k;
cin >> n >> m >> k;
vector<ll> a(k);
for(int i = 0;i < k;i++) cin >> a[i];
sort(a.begin(),a.end());//排序
ll ans = 0,flg = 0,sum = 0;//flg 标记
for(int i = 0;i < k;i++)
{
ll row = a[i] / m;//按行涂,row 表示该颜色可以涂几行
ans = max(ans,row);//最多的那种颜色最多涂几行
if(row >= 2)
{
sum += row;//k种颜色一共可一涂几行
}
}
if(sum >= n)
{
if(n & 1)//奇数,需要有颜色多贡献一行
{
if(ans >= 3)
flg = 1;
}
else flg = 1;
}
ans = 0;
sum = 0;
for(int i = 0;i < k;i++)
{
ll row = a[i] / n;//按列涂,row 表示该颜色可以涂几列
ans = max(ans,row);//最多的那种颜色最多涂几列
if(row >= 2)
{
sum += row;//k种颜色一共可一涂几列
}
}
if(sum >= m)
{
if(m & 1)//奇数,需要有颜色多贡献一行
{
if(ans >= 3) flg = 1;
}
else flg = 1;
}
if(flg) cout << "YES" <<endl;
else cout << "NO" <<endl;
}
return 0;
}