A. Creating a Character
分析 : 注意有的情况c==0或c全部给b是可以的
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll min(ll a,ll b){return a<b?a:b;}
ll max(ll a,ll b){return a>b?a:b;}
int main()
{
int t;
cin>>t;
while(t--)
{
ll a,b,c;
cin>>a>>b>>c;
if(a+c<=b) {
cout<<"0\n"; continue;
}
ll tmp=b+c-a;
if(tmp<0) cout<<max(c+1,1)<<"\n";
else cout<<max(c-tmp/2,(ll)0)<<"\n";
}
return 0;
} B. Zmei Gorynich 分析 :略
code :
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 104;
ll min(ll a,ll b){return a<b?a:b;}
ll max(ll a,ll b){return a>b?a:b;}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,flag=0; ll u,v,x,maxv=0,p=0,ans=0;
scanf("%d%I64d",&n,&x);
for(int i=1;i<=n;i++) {
scanf("%I64d%I64d",&u,&v);
if(u>=x) flag=1;
maxv=max(maxv,u-v);
p=max(p,u);
}
if(flag) printf("1\n");
else if(maxv<=0) printf("-1\n");
else {
ll num=(x-p)/maxv,ans=0;
x-=num*maxv;
ans+=num;
if(x>p) ans+=2;
else ans++;
printf("%I64d\n",ans);
}
}
return 0;
} C. The Number Of Good Substrings 分析 : s[ l ] == 1 的区间最长取长度为18的,如果区间更长,则肯定大于 |s| , 但是需要加上有前导0的情况。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 3;
int p[maxn];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char s[maxn];
scanf("%s",s+1);
int n=strlen(s+1),sum,ans=0;
for(int i=1;i<=n;i++)
if(s[i]=='0') p[i]=p[i-1]+1;
else p[i]=p[i-1];
for(int len=1;len<=18;len++) for(int i=1;i<=n-len+1;i++)
if(s[i]=='1') {
sum=0;
for(int j=0;j<len;j++)
sum=(sum<<1)+s[i+j]-'0';
if(sum>=len&&i-(sum-len)-1>=0&&sum-len==p[i-1]-p[i-(sum-len)-1]) ans++;
}
printf("%d\n",ans);
}
return 0;
} D. Coloring Edges
分析 : 发现无环的时候k=1,有环的时候k=2,有环时可令E(u->v,u>v) 为一种颜色,E(u->v , u<v) 为另一种颜色,即可保证没有同色环。那么重点在于判断是否有环存在,按照拓扑排序遍历即可(见代码)
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5004;
vector<int> p[maxn];
int deg[maxn],a[maxn],b[maxn];
bool top_sort(int n)
{
queue<int> q;
int cnt=0;
for(int i=1;i<=n;i++) if(!deg[i]) q.push(i);
while(!q.empty())
{
int x=q.front(),y;
cnt++; q.pop();
for(int i=0;i<p[x].size();i++) {
y=p[x][i];
deg[y]--;
if(!deg[y]) q.push(y);
}
}
return cnt==n;
}
int main()
{
int m,n;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) {
scanf("%d%d",&a[i],&b[i]);
p[a[i]].push_back(b[i]);
deg[b[i]]++;
}
if(top_sort(n)) {
printf("1\n");
for(int i=1;i<=m;i++) printf("1 ");
}
else
{
printf("2\n");
for(int i=1;i<=m;i++)
if(a[i]>b[i]) printf("1 ");
else printf("2 ");
}
return 0;
} E. Sum Queries?
分析 :只需要两个某一位同时不为0的数即可,所以题目转化为求两个数满足某一位都不为0的和最小为多少,建立线段树维护每一位上不为0的数中最小值和次小值。这题代码实现对编程技巧要求较高(参考了某位神犇的博客),代码值得反复玩味
code :
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2e9 + 1;
const int maxn = 2e5 + 3;
int a[maxn];
struct SegmentTree {
int l,r,minv[10],mn[10];
}t[maxn<<2];
void pushup(int p)
{
for(int i=0;i<10;i++) {
t[p].minv[i]=min(t[p*2].minv[i],t[p*2+1].minv[i]);
t[p].mn[i]=min(t[p*2].mn[i],t[p*2+1].mn[i]);
t[p].mn[i]=min(t[p].mn[i],max(t[p*2].minv[i],t[p*2+1].minv[i]));
}
}
void build(int p,int l,int r)
{
t[p].l=l,t[p].r=r;
for(int i=0;i<10;i++) t[p].minv[i]=t[p].mn[i]=INF;
if(l==r) {
for(int x=a[l],now=0;x;x/=10,now++)
if(x%10) t[p].minv[now]=a[l];
return;
}
int mid=(l+r)>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
pushup(p);
}
void update(int p,int k,int x)
{
if(t[p].l==t[p].r) {
for(int i=0;i<10;i++) t[p].minv[i]=t[p].mn[i]=INF;
for(int y=x,now=0;y;y/=10,now++)
if(y%10) t[p].minv[now]=x;
return;
}
int mid=(t[p].l+t[p].r)>>1;
if(mid>=k) update(p*2,k,x);
else update(p*2+1,k,x);
pushup(p);
}
pair<int,int> getmin(int p,int l,int r,int id)
{
if(t[p].l==l&&t[p].r==r) return make_pair(t[p].minv[id],t[p].mn[id]);
int mid=(t[p].l+t[p].r)>>1;
if(mid<l) return getmin(p*2+1,l,r,id);
else if(mid>=r) return getmin(p*2,l,r,id);
else {
pair<int,int> a=getmin(p*2,l,mid,id),b=getmin(p*2+1,mid+1,r,id);
return make_pair(min(a.first,b.first),min(min(a.second,b.second),max(a.first,b.first)));
}
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
while(q--)
{
int op;
scanf("%d",&op);
if(op==1) {
int k,x;
scanf("%d%d",&k,&x);
update(1,k,x);
}
else {
int l,r,ans=INF;
pair<int,int> tmp;
scanf("%d%d",&l,&r);
for(int i=0;i<10;i++) {
tmp=getmin(1,l,r,i);
if(tmp.first!=INF&&tmp.second!=INF) ans=min(ans,tmp.first+tmp.second);
}
if(ans==INF) printf("-1\n");
else printf("%d\n",ans);
}
}
return 0;
} 
京公网安备 11010502036488号