标签:
重现补的题目。思路:不要求一次性杀光一个节点里面的所有怪物。 所以我们可以用一个优先队列。优先去杀那些我们当前可以挑战的,然后注意下处理一个房间可能有多个怪物或者无怪物。当我们杀完第x个房间的怪物时候,那么就把x的下一层的怪物加入队列,如果x的下一层出现了空房间[即房间不存在怪物],那么再把该房间当做新的x,继续加入新x的下一层直到出现了有怪物的房间位置。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<functional>
#include<cstring>
#include<string>
using namespace std;
typedef long long int LL;
const int MAXN = 1005;
struct Node
{//怪物
int id, def, add_atk; //所在房间,防御值,击杀额外获得的攻击力
};
struct cmp
{//按防御值最低并且额外值最高排序[优先队列]
bool operator ()(const Node &a, const Node &b)
{
if (a.def == b.def)
{
return a.add_atk < b.add_atk;
}
return a.def > b.def;
}
};
bool cmp0(Node a, Node b)
{ //按防御值最低并且额外值最高排序[预处理第0号房间]
if (a.def == b.def)
{
return a.add_atk > b.add_atk;
}
return a.def < b.def;
}
vector<Node>GW[MAXN]; //GW[i]:第i个房间的怪物情况
vector<int>G[MAXN]; //图,保存树的结构
int n, m, t, atk, num[MAXN], vis[MAXN];
//点数,怪物数,样例数,每个房间的怪物数,访问数组
bool bfs()
{
priority_queue<Node, vector<Node>, cmp>Q; //怪物队列
queue<int>inq; //扩展队列,保存x,即保存能扩展下一层的房间号
inq.push(0); vis[0] = 1;
while (!inq.empty())
{
int top = inq.front(); inq.pop();
if (GW[top].size()) //非空房间
{
for (int i = 0; i < GW[top].size(); i++)
{ //加入此房间的怪物到怪物队列
Q.push(GW[top][i]);
}
}
else //此房间为空房间
{
for (int i = 0; i < G[top].size(); i++)
{ //继续想inq队列加入下一层结点,继续扩展
if (vis[G[top][i]] == 0)
{
vis[G[top][i]] = 1;
inq.push(G[top][i]);
}
}
}
}
while (!Q.empty())
{
Node front = Q.top(); Q.pop();
if (atk <= front.def) //当前最优都无法击杀,那么后面肯定击杀不了。
{
return false;
}
atk += front.add_atk;
num[front.id]--;
if (num[front.id] == 0) //此房间的怪物已经击杀完或者是空房间
{
for (int i = 0; i < G[front.id].size(); i++) //同上处理
{
if (vis[G[front.id][i]] == 0)
{
vis[G[front.id][i]] = 1;
inq.push(G[front.id][i]);
}
}
while (!inq.empty())
{
int top = inq.front(); inq.pop();
if (GW[top].size())
{
for (int i = 0; i < GW[top].size(); i++)
{
Q.push(GW[top][i]);
}
}
else
{
for (int i = 0; i < G[top].size(); i++)
{
if (vis[G[top][i]] == 0)
{
vis[G[top][i]] = 1;
inq.push(G[top][i]);
}
}
}
}
}
}
return true; //全部怪物击杀完成
}
void init()
{
memset(num, 0, sizeof(num));
memset(vis, 0, sizeof(vis));
for (int i = 0; i <= n; i++)
{
G[i].clear();
GW[i].clear();
}
}
int main()
{
scanf("%d", &t);
while (t--)
{
init();
scanf("%d%d", &n, &m);
for (int i = 0; i < n - 1; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
scanf("%d", &atk);
for (int i = 0; i < m; i++)
{
Node temp;
scanf("%d%d%d", &temp.id, &temp.def, &temp.add_atk);
GW[temp.id].push_back(temp);
num[temp.id]++;
}
if (bfs())
{
printf("Oh yes.\n");
}
else
{
printf("Good Good Study,Day Day Up.\n");
}
}
return 0;
}#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<set>
#include<vector>
using namespace std;
typedef long long int LL;
const int MAXN = 10000 + 5;
const int MAXZ = 105;
struct Node
{
int w, v; //价格,攻击力
int id, buff; //是否有buff加成
Node(int b = 0, int c = 0, int d = -1, int e = 0) :w(b), v(c), id(d), buff(c){};
void init(int a = 0, int b = 0, int c = -1, int d = -1)
{
w = a; v = b; id = c; buff = d;
}
};
Node Tk[MAXZ], Ss[MAXZ], Dw[MAXZ], Sw[MAXZ], TS[3][MAXN];
//头盔,首饰,单手武器,双手武器,TS[1]:防具组,TS[2]:武器组
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int m, a, b, c, d, ts = 0, ts2 = 0;
int wei, val, Buff, Id;
scanf("%d%d%d%d%d", &m, &a, &b, &c, &d);
for (int i = 0; i<a; i++) //头盔
{
scanf("%d%d", &wei, &val);
Node temp(wei, val, 0, 0);
Tk[i] = temp;
TS[1][ts++] = temp; //防具组:只选一个头盔
}
for (int i = 0; i<b; i++) //首饰
{
scanf("%d%d%d%d", &wei, &val, &Id, &Buff);
Node temp(Node(wei, val, Id, Buff));
Ss[i] = temp;
TS[1][ts++] = temp; //防具组:只选一个首饰
if (Id == -1 || Buff <= 0)
{
continue;
}
temp.init(Ss[i].w + Tk[Id].w, Ss[i].v + Tk[Id].v + Buff, 0, 0);
TS[1][ts++] = temp; //防具组:有buff加成的头盔+首饰
}
for (int i = 0; i<a; i++) //防具组:头盔+首饰
{
for (int j = 0; j<b; j++)
{
Node temp(Node(Tk[i].w + Ss[j].w, Tk[i].v + Ss[j].v, 0, 0));
TS[1][ts++] = temp;
}
}
for (int i = 0; i<c; i++) //单手武器
{
scanf("%d%d", &wei, &val);
Node temp(wei, val, 0, 0);
TS[2][ts2++] = temp; //武器组:只选一个单手武器
Dw[i] = temp;
}
for (int i = 0; i<c; i++) //武器组:一个单手武器+一个单手武器=双手武器
{
for (int j = i + 1; j<c; j++)//因为每种只有一个,所以j要从i+1开始
{
Node temp(Dw[i].w + Dw[j].w, Dw[i].v + Dw[j].v);
TS[2][ts2++] = temp;
}
}
for (int i = 0; i<d; i++) //双手武器
{
scanf("%d%d", &wei, &val);
Node temp(wei, val, 0, 0);
TS[2][ts2++] = temp; //武器组:只选一个双手武器。
}
//贪心求法:
LL ans = 0;
for (int i = 0; i<ts; i++)
{//在限有的金币下,x=只选防具的最大攻击力
if (TS[1][i].w <= m) //在限有的金币下
{
ans = max(ans, 1LL * TS[1][i].v);
}
}
for (int i = 0; i<ts2; i++)
{ //在限有的金币下,y=只选武器的最大攻击力
if (TS[2][i].w <= m) //在限有的金币下
{
ans = max(ans, 1LL * TS[2][i].v);
}
}
for (int i = 0; i<ts; i++)
{//z=选防具和武器搭配的最大攻击力
for (int j = 0; j<ts2; j++)
{
if (TS[1][i].w + TS[2][j].w <= m) //在限有的金币下
{
ans = max(ans, 1LL * (TS[1][i].v + TS[2][j].v));
}
}
}
printf("%lld\n", ans); //ans=max(x,y,z)
//////////////////////////分组背包求法//////////////////////////////////
int dp[3][MAXN];
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= 2; i++)
{
for (int k = 0; k <= m; k++)
{
dp[i][k] = dp[i - 1][k];
}
for (int k = 0; k<(i == 1 ? ts : ts2); k++)
{
for (int j = m; j >= TS[i][k].w; j--)
{
dp[i][j] = max(dp[i][j], dp[i - 1][j - TS[i][k].w] + TS[i][k].v);
}
}
}
printf("%d\n", dp[2][m]);
}
return 0;
}#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
using namespace std;
typedef long long int LL;
const int MAXN = 100 + 5;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000009;
int D[MAXN][MAXN], g[MAXN][MAXN];
//D:起点到其他点的最短路距离
int n, minval, dist[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
//minval:起点到终点的最短路距离,dist:方向向量
struct Node
{
int x, y;
int val;
};
struct cmp
{
bool operator()(const Node &a, const Node &b)
{
return a.val > b.val;
}
};
bool check(int x, int y)//是否越界
{
return x >= 1 && x <= n&&y >= 1 && y <= n;
}
void bfs(Node start)
{
priority_queue<Node, vector<Node>, cmp>Q;
memset(D, -1, sizeof(D));
Q.push(start);
D[start.x][start.y] = start.val;
while (!Q.empty())
{
Node t = Q.top(); Q.pop();
Node next;
for (int i = 0; i < 4; i++)
{
next.x = t.x + dist[i][0];
next.y = t.y + dist[i][1];
if (check(next.x, next.y) && D[next.x][next.y] == -1 && next.x + next.y <= n + 1)
{ //g[next.x][next.y]为当前值,g[n - next.y + 1][n - next.x + 1]为对角线对称点值
next.val = t.val + g[next.x][next.y] + (next.x + next.y == n + 1 ? 0 : g[n - next.y + 1][n - next.x + 1]);
D[next.x][next.y] = next.val;
Q.push(next);
}
}
}
minval = INF;
for (int i = 1; i <= n; i++)//找到最短路
{
minval = min(minval, D[i][n + 1 - i]);
}
}
int dp[MAXN][MAXN];
int dfs(int x, int y)
{
if (dp[x][y] != -1)//记忆化搜索
{
return dp[x][y];
}
int nextx, nexty, cnt = 0;
for (int i = 0; i < 4; i++)
{
nextx = x + dist[i][0];
nexty = y + dist[i][1];
if (check(nextx, nexty) && nextx + nexty <= n + 1 && D[nextx][nexty] + g[x][y] + (x + y == n + 1 ? 0 : g[n - y + 1][n - x + 1]) == D[x][y])
{
cnt = (cnt + dfs(nextx, nexty)) % MOD;
}
}
dp[x][y] = cnt%MOD;
return dp[x][y];
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
scanf("%d", &g[i][j]);
}
}
Node start; start.x = 1; start.y = 1, start.val = g[1][1] + g[n][n]; //起点。
bfs(start); //求(1,1)到其他点的最短路距离
/*for (int i = 1; i <= n; i++) //Debug
{
for (int j = 1; j <= n; j++)
{
printf("%d ", D[i][j]);
}
printf("\n");
}*/
memset(dp, -1, sizeof(dp));
LL ans = 0; dp[1][1] = 1;
for (int i = 1; i <= n; i++)
{
if (D[i][n + 1 - i] == minval)
{
ans = (ans + dfs(i, n + 1 - i)) % MOD;
}
}
printf("%lld\n", ans);
}
return 0;
}#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<set>
using namespace std;
typedef long long int LL;
const int MAXN=100000+5;
char str[MAXN];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%s",str); bool flag=true;
for(int i=0;i<strlen(str)-1;i++)
{
if(str[i]=='#'&&str[i+1]=='#')
{
flag=false;
break;
}
}
printf(flag?"yes\n":"no\n");
}
return 0;
}
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
using namespace std;
typedef long long int LL;
const int MAXN = 1000000 + 5;
struct Node
{
int H;
int id;
}A[MAXN];
void solve(int n)
{
LL ans = 0;
stack<Node>st;
for (int i = 0; i < n; i++)
{
if (st.empty())
{
st.push(A[i]);
}
else
{
LL top_h = 0;
LL cnt = 0, tot = 0;
while (!st.empty())
{
Node tmp = st.top();
top_h = tmp.H;
if (A[i].H > tmp.H)
{
cnt += 1LL * (A[i].id - tmp.id);
tot += 1LL * (A[i].id - tmp.id)*tmp.H;
A[i].id = tmp.id;
st.pop();
}
else
{
break;
}
}
ans += 1LL * (cnt* min(1LL * A[i].H, top_h) - tot);
st.push(A[i]);
}
}
printf("%lld\n", ans);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &A[i].H);
A[i].id = i;
}
solve(n);
}
return 0;
}#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
typedef long long int LL;
const int MAXM = 1e9;
LL p, ans;
int n, cnt, num[55], temp[55], vis[55];
LL gcd(LL x, LL y)
{
return y ? gcd(y, x % y) : x;
}
void DFS(LL i, LL w, LL k)
{//i:当前的位置,w:之前集合的最小公倍数,k:奇偶
if (w > MAXM) //剪枝。
{
return;
}
for (; i < cnt; i++)
{
p = num[i] / gcd(num[i], w) * w;
ans += k*(MAXM / p);
DFS(i + 1, p, -k);
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n); cnt = 0;
bool one = false;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < n; i++)
{
scanf("%d", &temp[i]);
if (temp[i] == 0)
{
vis[temp[i]] = 1;
}
if (temp[i] == 1)//出现1
{
one = true;
}
}
if (one)
{
printf("0\n");
continue;
}
sort(temp, temp + n);
for (int i = 0; i < n; i++) //删除里面的倍数
{
for (int j = i + 1; j < n; j++)
{
if (vis[i] == 0 && vis[j] == 0 && temp[j] % temp[i] == 0)
{
vis[j] = 1;
}
}
if (vis[i] == 0)
{
num[cnt++] = temp[i];
}
}
ans = 0; DFS(0, 1, 1);
printf("%lld\n", MAXM - ans);
}
}#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<set>
using namespace std;
typedef long long int LL;
const int MAXN = 10000;
char str[MAXN];
int main()
{
int t;
scanf("%d", &t);
getchar();
while (t--)
{
gets(str);
set<char>word;
for (int i = 0; i<strlen(str); i++)
{
if (str[i] >= 'a'&&str[i] <= 'z'&&!word.count(str[i]))
{
word.insert(str[i]);
}
}
printf("%d\n", word.size());
}
return 0;
}标签:
原文地址:http://blog.csdn.net/slime_kirito/article/details/51140646