本菜鸡只写了前 四题...
A题:Creating a Character
题意:
给两个个属性,力量,智力,以及你有的分配点数。给出基础力量智力数值,以及拥有的剩余分配点数值。你需要将点数分配完,并且保证力量的 值大于智力,输出能够分配的可能数。不能就输出0.
思路:
我列了一个方程:设 力量为a,智力为b,分配点数值为c. 设分到力量的为 X,分到 智力为 Y. 则 a + X = b + Y , X + Y = c ; 其中 Y 为 b能够分配的最大值,求解 Y 即可. 由于有奇偶问题,所以我就取
max(c-X,Y) 作为Y的解
code:
#include <iostream> #include <algorithm> #include <cmath> #include <cstring> #include <string> using namespace std; int main(){ int T; cin>>T; while(T--){ int a,b,c; cin>>a>>b>>c; int x,y; x = (c-a+b)/2; y = (a-b+c)/2; int ans = max(c-x,y); if(b+c<a) cout<<c+1<<endl; else if(a+c<=b) cout<<0<<endl; else cout<<ans<<endl; } }
B题:Zmei Gorynich
题意:
给 N 个技能组,每个技能组 会造成 a 点伤害, 如果对手在收到 a点伤害后剩余的血量 大于0 则会 在该回合 回复 b点。 可以选择任意技能组,重复任意次。输出能打败对手的最少回合数.
思路:
由于在某回合造成伤害后 对手会 回血,所以我们选取其中 造成伤害最大的作为最后一击。其他使用技能所造成的伤害即是 (a-b),我们再选取 (a-b)最大的技能去计算剩下还需打多少次即可。
code:
#include <algorithm> #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #define IOS ios::sync_with_stdio(0); cin.tie(0); using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double Pi = acos(-1.0); const double esp = 1e-9; const int inf = 0x3f3f3f3f; const int maxn = 1e5+7; const int maxm = 1e6+7; const int mod = 1e9+7; int main(){ IOS int T; cin >> T; while (T--){ int n, m; cin >> n >> m; bool can = true; int cnt = 0; int maxx = 0;//最大的 int maxsub = 0;//最大减少生命值 for(int i=1;i<=n;i++){ int x, y; scanf("%d%d", &x, &y); maxx = max(maxx, x);//取最大威力 maxsub = max(maxsub, x - y);//最大减少生命值 //无法处理 if (x < m && x - y <= 0){ cnt++; if (cnt == n)//都无法处理,false can = false; } } if (can){ if (maxx >= m)//可以一拳打死 cout << 1 << endl; else{ int rest = m - maxx; if (rest % maxsub == 0)//如果整数次刚好剩下最大威力 cout << rest / maxsub + 1 << endl; else cout << rest / maxsub + 2 << endl;//否则再攻击一次使生命值小于最大威力 } } else cout << -1 << endl;//不可以 } }
C. The Number Of Good Substrings
题意:
给一个01串,选择一个区间 (l,r) 如果 区间长度 r - l +1 == (该区间01串形成的二进制数转换成十进制的数值),统计符合这样区间的个数
思路:
我们观察一下就会发现,要满足条件,即所选区间长度肯定大于等于从第一个 1 开始往后形成的二进制数值。(比如像 111 (8) 要形成这样即需要在 111 前面补上 5个前缀0)
所以我们对01串遍历时统计每一个连续的前导0个数,然后暴力枚举(延长01串),如果 满足所选区间长度大于等于所形成的二进制数 即符合条件。
code:
#include <algorithm> #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <vector> #define IOS ios::sync_with_stdio(0); cin.tie(0); #define mp make_pair #define Accept 0 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double Pi = acos(-1.0); const double esp = 1e-9; const int inf = 0x3f3f3f3f; const int maxn = 1e5+7; const int maxm = 1e6+7; const int mod = 1e9+7; int a[maxm]; string s; int main(){ IOS int T; cin>>T; while(T--){ int ans = 0; cin>>s; int len = s.length(); for(int i=0;i<len;i++){ if(s[i]=='0') a[i] =0; else a[i] = 1; } int cnt = 0;//前导零长度 for(int i=0;i<len;i++){ if(!a[i]) {cnt++; continue;} else{ int tmp = 0; for(int j=0;j+i<len&&j<30;j++){ tmp = (tmp<<1)|a[i+j];//取后面位数 if(cnt+j+1>=tmp) ans++; } cnt = 0; } } cout<<ans<<endl; } }
D.Coloring Edges
题意:给出一张有向图,你需要对图上的边进行上色。不能对环全部染成同样的颜色,求最后最多需要多少种颜色,以及输出每条边的染色情况
思路:对于有向环判环我们用 拓扑排序处理下,把所有的环部分处理出来,如果没有环,则全为1,否则对环内部最后一条边输出2,用一个增序判断即可)
#include <algorithm> #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <vector> #include <stack> #include <queue> #define IOS ios::sync_with_stdio(0); cin.tie(0); #define mp make_pair #define Accept 0 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double Pi = acos(-1.0); const double esp = 1e-9; const int inf = 0x3f3f3f3f; const int maxn = 5e3+7; const int maxm = 5e3+7; const int mod = 1e9+7; struct Edge { int u,v; int next; }edge[maxm]; bool flag; int ans; int in[maxn]; int head[maxn]; int vis[maxn]; int top; queue<int>Q; void init(){ memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); top = 0; flag = true; } void add(int u,int v){ edge[top].v = v; edge[top].next = head[u]; edge[top].u = u; head[u] = top++; } void topo(int n,int m){ for(int i=1;i<=n;i++) if(!in[i]) Q.push(i); while(!Q.empty()){ int u = Q.front(); Q.pop(); for(int i = head[u]; ~i ;i= edge[i].next){ int v = edge[i].v; in[v]--; if(!in[v]) Q.push(v); } } for(int i=1;i<=n;i++){ if(in[i]!=0) flag = false; } if(flag) { cout<<1<<endl; for(int i=0;i<m;i++) cout<<1<<" "; }else{ cout<<2<<endl; for(int i=0;i<m;i++){ if(edge[i].u<edge[i].v) cout<<1<<" "; else cout<<2<<" "; } } } int main(){ IOS int n,m; cin>>n>>m; init(); int u,v; for(int i=0;i<m;i++){ cin>>u>>v; add(u,v); in[v]++; } topo(n,m); return 0; }