HDU #1863 : 暢通工程
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1863
題意:有n個點和m條權值邊,問將整個圖連通最少需要花費多少。
思路:最小生成樹。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 1e2 + 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
struct node
{
int to;
int cost;
};
int m, n, cnt;
bool used[maxn];
vector<node> edge[maxn];
struct cmp
{
bool operator()(node a, node b)
{
return a.cost > b.cost;
}
};
void init()
{
cnt = 0;
cl0(used);
for (int i = 1; i <= n; i++)
edge[i].clear();
}
int main()
{
while (~scanf("%d%d", &m, &n)) {
if (m == 0)break;
init();
int aa, bb, cc; cc = INF;
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &x, &y, &z);
edge[x].push_back(node{ y,z });
edge[y].push_back(node{ x,z });
if (z < cc) {
cc = z; aa = x; bb = y;
}
}
used[aa] = true; used[bb] = true;
priority_queue<node, vector<node>, cmp> que;
for (int i = 0; i < edge[aa].size(); i++)
que.push(edge[aa][i]);
for (int i = 0; i < edge[bb].size(); i++)
que.push(edge[bb][i]);
int now = 2, ans = cc;
while (now < n && !que.empty()) {
node u = que.top(); que.pop();
if (!used[u.to]) {
now++;
used[u.to] = true;
ans += u.cost;
for (int i = 0; i < edge[u.to].size(); i++)
que.push(edge[u.to][i]);
}
}
if (now != n)
puts("?");
else
printf("%d\n", ans);
}
return 0;
}
HDU #1053 : Entropy
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1053
題意:給一個字符串,問最少需要多少位就可以將它編碼。
思路:Huffman編碼。優先隊列,每次把最小的兩塊拿出來相加再塞回隊列,隊列裏最後一個元素就是答案。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 1e5 + 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int now;
string str;
int cnt[30];
map<char, int> mp;
void init()
{
mp.clear();
cl0(cnt);
now = 0;
}
struct cmp
{
bool operator()(int a, int b)
{
return a > b;
}
};
int main()
{
while (cin >> str) {
if (str == "END")break;
init();
int len = str.length();
for (int i = 0; i < len; i++) {
if (mp[str[i]] == 0)
mp[str[i]] = ++now;
cnt[mp[str[i]]]++;
}
priority_queue<int, vector<int>, cmp> que;
int ans = 0;
for (int i = 1; i <= now; i++)
que.push(cnt[i]);
if (que.size() == 1)
ans = cnt[1];
else {
while (que.size() > 1) {
int a = que.top(); que.pop();
int b = que.top(); que.pop();
que.push(a + b);
ans += a + b;
}
}
printf("%d %d %.1f\n", len * 8, ans, (double)len * 8 / ans);
}
return 0;
}
HDU #2021 : 發工資咯:)
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=2021
題意:將正整數n表示爲若干個100、50、10、5、2和1的和,問最少需要多少個。
思路:因爲對於每兩個值a、b(a>b)都有a>=2b,所以直接貪心即可。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 1e2 + 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int n, m;
int a[6] = { 100,50,10,5,2,1 };
int main()
{
while (~scanf("%d", &n)) {
if (n == 0)break;
int ans = 0;
while (n--) {
scanf("%d", &m);
for (int i = 0; i < 6; i++) {
ans += m / a[i];
m %= a[i];
}
}
printf("%d\n", ans);
}
return 0;
}
HDU #4221 : Greedy?
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=4221
題意:有n件事,每件事有完成所需時間c,並且應該在時間d前完成。問所有事最少超時之和爲多久。
思路:按d從小到大排列按順序完成,累加時間就是答案。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const double _e = 10e-6;
const int maxn = 1e5 + 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
struct node
{
ll c, d;
};
int n, m;
node a[maxn];
bool cmp(node a, node b)
{
return a.d < b.d;
}
int main()
{
int t;
scanf("%d", &t);
for (int _ = 1; _ <= t; _++) {
ll ans = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%lld%lld", &a[i].c, &a[i].d);
sort(a + 1, a + n + 1, cmp);
ll now = 0;
for (int i = 1; i <= n; i++) {
now += a[i].c;
ans = max(ans, now - a[i].d);
}
printf("Case %d: %lld\n", _, ans);
}
return 0;
}
HYSBZ #1826 : 緩存交換
傳送門:https://www.lydsy.com/JudgeOnline/problem.php?id=1826
題意:cache調度,按順序給出n個內存塊。問怎麼調度miss最少。
思路:當cache滿時,如果miss發生就將cache中在之後最晚再出現的塊踢掉。
優先隊列,記錄內存塊編號及它下一次出現的時間,如果再也不出現時間就爲INF,按照下次時間從大到小排。
由於n<=1e5,但內存塊編號<=1e9,可以用map來搞。
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#include<functional>
#include<bitset>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs (id*2+1)
#define Mod(a,b) a<b?a:a%b+b
#define cl0(a) memset(a,0,sizeof(a))
#define cl1(a) memset(a,-1,sizeof(a))
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9 + 10;
const double _e = 10e-6;
const int maxn = 1e5 + 10;
const int matSize = 9;
const int dx[4] = { 0,0,1,-1 }, dy[4] = { 1,-1,0,0 };
const int _dx[8] = { -1,-1,-1,0,0,1,1,1 }, _dy[8] = { -1,0,1,-1,1,-1,0,1 };
int x, y, z;
char c;
int m, n, cnt;
int a[maxn];
map<int, int> mp;
bool used[maxn];
struct node
{
int id;
int nxt;
};
struct cmp
{
bool operator()(node a, node b)
{
return a.nxt < b.nxt;
}
};
int main()
{
while (~scanf("%d%d", &n, &m)) {
mp.clear(); cnt = 0; cl0(used);
queue<int> nxt[maxn];
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if (mp[a[i]] == 0)
mp[a[i]] = ++cnt;
nxt[mp[a[i]]].push(i);
}
for (int i = 1; i <= cnt; i++)
nxt[i].push(INF);
priority_queue<node, vector<node>, cmp> que;
int now = 0, ans = 0;
for (int i = 1; i <= n; i++) {
if (!used[mp[a[i]]]) {
ans++; used[mp[a[i]]] = true;
if (now != m)
now++;
else {
node u = que.top(); que.pop();
used[u.id] = false;
}
}
nxt[mp[a[i]]].pop();
que.push(node{ mp[a[i]],nxt[mp[a[i]]].front() });
}
printf("%d\n", ans);
}
return 0;
}