G - 今年暑假不AC
我真是服了...
本来想写道水题然后去写工数,结果卡了快半小时。最后发现ans忘了每次清零了QAQ
言归正传,典型的贪心。很容易让人想到智力大冲浪。只不过这道题每个任务价值一定,时间不同。
贪心策略:先完成持续时间短的
#include <iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
struct Node{
int L,R;
int tim;
bool operator <(const Node& b) const {
return tim<b.tim;}
};
Node a[110];
int t[110],ans=0;
int main()
{
for(;;)
{
ans=0;
cin>>n;
if(!n) break;
for(int i=1;i<=n;i++) {cin>>a[i].L>>a[i].R;a[i].tim=a[i].R-a[i].L;}
sort(a+1,a+n+1);
memset(t,0,sizeof(t));
// for(int i=1;i<=n;i++) cout<<a[i].tim<<endl;
for(int i=1;i<=n;i++)
{
int flag=1;
for(int j=a[i].L;j<a[i].R;j++)
if(t[j]) {flag=0;break;}
if(!flag) continue;
for(int j=a[i].L;j<a[i].R;j++) t[j]=1;
ans++;
}
cout<<ans<<endl;
}
return 0;
}
H-hero
典型的贪心。大意为你要1VN,你每次打1,受伤害为对方所有人攻击力之和,求将所有敌人击败前,你受伤害的最小值。
只要按照伤害/血量排序即可
A-Filp Game
题意:有一个4*4的棋盘,棋盘上有黑白格,每一次你可以翻其中的一个格子。一个格子(x,y)如果被翻,它相邻的前后左右四个格子(如果在棋盘上)也要翻转。现在给你一个初始的棋盘状态,问把这个棋盘翻转到全黑或全白的最少次数;若不能达到全黑或全白,输出Impossible。
搜索,用DFS 好像BFS也可以?我是枚举了所有情况,后来看题解发现只要枚举第一行就行了,往后翻转情况是确定的。太强了orz
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int dx[] = {0, 0, 0, 1, -1};
int dy[] = {0, 1, -1, 0, 0};
int ans = 0x3f3f3f3f;
int flip(int xx, int yy, int tmp)//依次翻转五个格子
{
for (int i=0; i<5; i++) {
int x = xx + dx[i], y = yy + dy[i];
if (x >=0 && x <4 && y>=0 && y < 4)
tmp ^= 1 << (x * 4 + y);
}
return tmp;
}
//cur当前行,num当前步数,state当前棋盘状态,flag表示期望黑或白
void dfs(int cur, int num, int state, int flag)
{
if (cur == 4 && (state == 0xffff || state == 0)) {//更新答案
ans = min(ans, num);
}
if (cur == 4) return;//返回条件
int i = cur - 1;
for (int j=0; j<4; j++) {//使上一行全黑/白
if (((state & (1 << (i * 4 + j))) >> (i * 4 + j)) ^ flag) {
state = flip(cur, j, state);
num++;
continue;
}
}
dfs(cur + 1, num, state, flag);
}
void solve(int st)
{
for (int i=0; i<16; i++) {//枚举第一行
int num = 0, state = st;
for (int j=0; j<4; j++) {
if (i & (1 << j)) {
state = flip(0, j, state);
num++;
}
}
dfs(1, num, state, 0);
dfs(1, num, state, 1);
}
if (ans == 0x3f3f3f3f)
puts("Impossible");
else printf("%d\n", ans);
}
int main()
{
char s[8];
int st = 0;
for (int i=0; i<4; i++) {
scanf("%s", s);
for (int j=0; j<4; j++) {
st <<= 1;
st += (s[j] == 'b') ? 1 : 0;
}
}
solve(st);
return 0;
}
用到了尺取法与set函数
单独拉出来写,在此不再赘述。