http://codeforces.com/gym/100553
题意:给定一个黑白相间的n*m矩阵,每次可以选择一个矩形,将其中的颜色的进行反转。问最少多少次操作可以将矩阵变为纯色。
分析:先反转所有偶数行,再反转所有偶数列即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
int x[11000],y[11000];
int ans;
int main()
{
freopen("alter.in","r",stdin);
freopen("alter.out","w",stdout);
int n,m;
cin>>n>>m;
ans=(n/2)+(m/2);
cout<<ans<<endl;
for (int i=1;i<=n/2;i++)
cout<<i*2<<" "<<1<<" "<<i*2<<" "<<m<<endl;
for (int i=1;i<=m/2;i++)
cout<<1<<" "<<2*i<<" "<<n<<" "<<2*i<<endl;
return 0;
}
题意:餐厅里有道菜,由n种原料构成,每种原料最多为g[i],定义Albert的满意度为
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
struct node
{
double k;
int id;
}a[1100000];
int n,num;
const double eps=1e-12;
int A,B;
int g[1100000],x[1100000],y[1100000];
double ans[1100000];
int cmp(node a,node b)
{
return a.k>b.k;
}
double maxx,minn;
int main()
{
freopen("burrito.in","r",stdin);
freopen("burrito.out","w",stdout);
scanf("%d %d %d",&n,&A,&B);
for (int i=1;i<=n;i++)
{
scanf("%d %d %d",&g[i],&x[i],&y[i]);
if (x[i]==0) a[i].k=0;
else if (y[i]==0) a[i].k=1e8;
else
{
a[i].k=(double)x[i]/y[i];
}
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for (int i=1;i<=n;i++)
{
if (y[a[i].id]==0) ans[a[i].id]=g[a[i].id];
else if (x[a[i].id]==0) ans[a[i].id]=0;
else
{
double d=g[a[i].id];
d=min(d,(double)(B-minn)/(double)(y[a[i].id]));
ans[a[i].id]=d;
}
maxx+=ans[a[i].id]*(double)x[a[i].id];
minn+=ans[a[i].id]*(double)y[a[i].id];
}
if (maxx+eps<A||minn-eps>B) printf("-1 -1\n");
else
{
printf("%.10f %.10f\n",maxx,minn);
for (int i=1;i<=n;i++)
{
printf("%.10f",ans[i]);
if (i!=n) printf(" ");
else printf("\n");
}
}
return 0;
}
题意:题目描述比较繁琐,简单说就是给你一个长度小于250的16进制序列。给你一些hash函数f的系数 ai 。如果一个16进制序列蕴含用户 uk 的消息,当且仅当,对于任意的hash函数,统计公式计算:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
using namespace std;
int n,m;
bitset<1100> bv;
int a[1100];
int u[1100];
int cal(char x)
{
if (x>='0'&&x<='9') return x-'0';
else return x-'a'+10;
}
int q,k;
int ans,way[1100];
string s[1100];
int main()
{
freopen("filter.in","r",stdin);
freopen("filter.out","w",stdout);
cin>>m>>n;
for (int i=1;i<=n;i++)
cin>>a[i];
cin>>q;
for (int i=0;i<q;i++)
{
cin>>s[i];
}
cin>>k;
for (int i=1;i<=k;i++)
cin>>u[i];
for (int i=0;i<q;i++)
{
int l=s[i].size();
string ss="";
int now=0;
for (int kk=0;kk<m/4;kk++)
{
int x=cal((char)s[i][kk]);
for (int ll=1;ll<=4;ll++)
ss+=(char)(x%2+'0'),x/=2;
}
if (m%4)
{
int x=cal((char)s[i][l-1]);
for (int ll=0;ll<m%4;ll++)
ss+=(char)(x%2+'0'),x/=2;
}
//cout<<ss<<endl;
bitset<1100> bv(ss);
for (int j=1;j<=k;j++)
{
int flag=0;
for (int ll=1;ll<=n;ll++)
if (!bv[m-1-((u[j]%m)*(a[ll]%m))%m])
{
flag=1;
break;
}
if (!flag)
{
ans++;
way[ans]=i;
break;
}
}
}
printf("%d",ans);
for (int i=1;i<=ans;i++)
printf(" %d",way[i]);
printf("\n");
return 0;
}
题意:有n个飞船,和一个空间站(无论何时,飞船都在空间站的同侧),每个飞船有一个位置 xi ,空间站在0号位置,第i个飞船有一条绳,将其与第i-1个飞船连接在一起,1号飞船与空间站相连。我们可以每次将一个飞船移动到任意位置。问,最多保留多少个飞船处于原位置,使得任意两条绳子不相交(包含不算)。
分析:按照昂神的题解,此题的答案等于飞船从前往后的标号序列,拥有的最长的先递增后递减的子序列的长度。之后我们可以nlogn前后扫两边最长上升子序列长度即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
struct node
{
int x,id;
}a[210000];
int n;
int cmp(node a,node b)
{
return a.x<b.x;
}
struct data{
int l,r;
int maxx;
}tr[2000001];
int flag=0,pos;
void build(int k,int s,int t)
{
tr[k].l=s;tr[k].r=t;
if(s==t)
{
tr[k].maxx=0;
return;
}
int mid=(s+t)>>1;
build(k<<1,s,mid);
build(k<<1|1,mid+1,t);
tr[k].maxx=max(tr[k<<1].maxx,tr[k<<1|1].maxx);
}
void change(int k,int a,int c)
{
int l=tr[k].l,r=tr[k].r;
if(r==l)
{
tr[k].maxx=max(tr[k].maxx,c);
return;
}
int mid=(l+r)>>1;
if (a<=mid) change(k<<1,a,c);
else change(k<<1|1,a,c);
tr[k].maxx=max(tr[k<<1].maxx,tr[k<<1|1].maxx);
}
int ask(int k,int a,int b)
{
int l=tr[k].l,r=tr[k].r;
if(a==l&&b==r)
{
return tr[k].maxx;
}
int mid=(l+r)>>1;
if(b<=mid) return ask(k<<1,a,b);
else if(a>mid) return ask(k<<1|1,a,b);
else return max(ask(k<<1,a,mid),ask(k<<1|1,mid+1,b));
}
int l[210000],r[210000];
int main()
{
freopen("improvements.in","r",stdin);
freopen("improvements.out","w",stdout);
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>a[i].x,a[i].id=i;
}
sort(a+1,a+1+n,cmp);
build(1,1,n);
for (int i=1;i<=n;i++)
{
if (a[i].id!=1)
{
int maxx=ask(1,1,a[i].id-1);
l[i]=maxx+1;
change(1,a[i].id,l[i]);
}
else l[i]=1,change(1,a[i].id,1);
}
build(1,1,n);
for (int i=n;i>=1;i--)
{
if (a[i].id!=1)
{
int maxx=ask(1,1,a[i].id-1);
r[i]=maxx+1;
change(1,a[i].id,r[i]);
}
else r[i]=1,change(1,a[i].id,1);
}
int maxx=0;
for (int i=1;i<=n;i++)
maxx=max(maxx,l[i]+r[i]-1);
cout<<maxx<<endl;
return 0;
}
题意:给定一个n小于等于50的全排列删去中间空格后的字符串序列。要求让还原成原来的全排列形式。
分析:先判断出n的大小,然后dfs搜索一下即可。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
int pp[51];
int way[51];
string s;
int l,n;
int flag;
void dfs(int pos,int num)
{
if (pos==l)
{
flag=1;
for (int i=1;i<=n;i++)
{
printf("%d",way[i]);
if (i!=n) printf(" ");
else printf("\n");
}
return ;
}
if (!pp[s[pos]-'0']&&s[pos]-'0'<=n)
{
pp[s[pos]-'0']=1;
way[num]=s[pos]-'0';
dfs(pos+1,num+1);
pp[s[pos]-'0']=0;
if (flag) return;
}
if (pos+1<l&&!pp[(s[pos]-'0')*10+s[pos+1]-'0']&&(s[pos]-'0')*10+s[pos+1]-'0'<=n)
{
pp[(s[pos]-'0')*10+s[pos+1]-'0']=1;
way[num]=(s[pos]-'0')*10+s[pos+1]-'0';
dfs(pos+2,num+1);
pp[(s[pos]-'0')*10+s[pos+1]-'0']=0;
if (flag) return;
}
}
int now;
int main()
{
freopen("joke.in","r",stdin);
freopen("joke.out","w",stdout);
pp[0]=1;
cin>>s;
l=s.size();
for (int i=1;i<=50;i++)
{
n++;
if (i<10) now+=1;
else now+=2;
if (now==l) break;
}
dfs(0,1);
return 0;
}
题意:有n(<=1000)辆汽车在 ai 到 bi 的区间内周期往复。有m(<=1000)个询问,问在t时刻,在 li 到 ri 区间内有多少辆汽车。
分析:模拟下就行。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
int n,m;
int l[1100],r[1100],d[1100];
int t,ll,rr;
int cal(int x,int t)
{
t%=d[x];
if (t<=r[x]-l[x])
{
return l[x]+t;
}
else
{
t-=(r[x]-l[x]);
return r[x]-t;
}
}
int main()
{
freopen("knockout.in","r",stdin);
freopen("knockout.out","w",stdout);
cin>>n>>m;
for (int i=1;i<=n;i++)
{
cin>>l[i]>>r[i];
d[i]=(r[i]-l[i])*2;
}
for (int i=1;i<=m;i++)
{
cin>>ll>>rr>>t;
int num=0;
for (int i=1;i<=n;i++)
{
int pos=cal(i,t);
//cout<<pos<<endl;
if (pos>=ll&&pos<=rr) num++;
}
cout<<num<<endl;
}
return 0;
}