Codeforces Round #277 (Div. 2)

来源:互联网 发布:nat123 80端口 免费 编辑:程序博客网 时间:2024/04/30 06:27

A题。。。水题。。

#include<cstdio>#include<cstring>#include<algorithm>#define ll __int64using namespace std;int main(){ll n;while(scanf("%I64d",&n)==1){if(n&1){ll ans=(ll)n/(ll)2-n;printf("%I64d\n",ans);}else{ll ans=(ll)n/(ll)2;printf("%I64d\n",ans);}}return 0;}
B题。。。个人觉得要点想法。。。本人FST了,写法出了点问题,有一种情况无法判断(第31组数据。。)。。。
先把答案矩阵(A矩阵)全部置为1,然后看B矩阵,如果这个点是0,就把这一行一列都置成0,然后统计答案矩阵行列1的个数,最后看B矩阵,如果B矩阵上一个位置是1,那么这一行或一列最少要有一个1,如果没有就是NO了。。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=110;int mp[MAXN][MAXN];int row[MAXN],col[MAXN];int ans[MAXN][MAXN];int main(){int n,m,i,j,k;while(scanf("%d%d",&n,&m)==2){memset(row,0,sizeof(row));memset(col,0,sizeof(col));for(i=0;i<n;i++)for(j=0;j<m;j++)ans[i][j]=1;for(i=0;i<n;i++){for(j=0;j<m;j++){scanf("%d",&mp[i][j]);if(!mp[i][j]){for(k=0;k<n;k++)ans[k][j]=0;for(k=0;k<m;k++)ans[i][k]=0;}}}for(i=0;i<n;i++)for(j=0;j<m;j++){row[i]+=ans[i][j];col[j]+=ans[i][j];}int flag=1;for(i=0;i<n;i++){for(j=0;j<m;j++){if(mp[i][j]&&!ans[i][j]){if(row[i]==0&&col[j]==0){flag=0;break;}}}}if(!flag){printf("NO\n");continue;}printf("YES\n");for(i=0;i<n;i++){for(j=0;j<m;j++)printf("%d ",ans[i][j]);printf("\n");}}return 0;}

C题

首先,按上下的次数是一定的,还有就是光标在左边就只要改变左边就好,在右边只要改变右边就好,比如abcdcbz,可以把a变成z花1步,把z变成a也是花一步,边其中一个就可以,所以直接模拟就是。。而且光标只要在其中一半移动就行。

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int MAXN=100010;char str[MAXN];int cnt[MAXN];int main(){int n,p,i,j;while(scanf("%d%d",&n,&p)==2){scanf("%s",str+1);int ans=0;int l=MAXN+1;int r=-1;memset(cnt,0,sizeof(cnt));for(i=1;i<=n/2;i++){cnt[i]=abs(str[i]-str[n-i+1]);if(cnt[i]){l=min(l,i);r=max(r,i);}if(cnt[i]>13)cnt[i]=26-cnt[i];ans+=cnt[i];}if(l==MAXN+1){printf("%d\n",ans);continue;}if(n&1){int mid=n/2+1;if(p<mid){if(p>=r)ans+=p-l;else if(p<=l)ans+=r-p;else{int temp1=r-p;int temp2=p-l;int temp=min(temp1,temp2);ans+=temp+r-l;;}}else if(p>mid){l=n-l+1;r=n-r+1;swap(l,r);if(p>=r)ans+=p-l;else if(p<=l)ans+=r-p;else{int temp1=r-p;int temp2=p-l;int temp=min(temp1,temp2);ans+=temp+r-l;;}}else{ans+=mid-l;}}else{int mid=n/2;if(p<=mid){if(p>=r)ans+=p-l;else if(p<=l)ans+=r-p;else{int temp1=r-p;int temp2=p-l;int temp=min(temp1,temp2);ans+=temp+r-l;;}}else{l=n-l+1;r=n-r+1;swap(l,r);if(p>=r)ans+=p-l;else if(p<=l)ans+=r-p;else{int temp1=r-p;int temp2=p-l;int temp=min(temp1,temp2);ans+=temp+r-l;;}}}printf("%d\n",ans);}return 0;}/*7 4abcdcba7 4azcdcba7 6azcdcba7 5azcdcba6 3abzcba6 6abzcba6 1abczbb*/
D题

比赛时不会的题。。

就是以每个点为根,遍历生成一棵树,根节点的权值必须不小于其他的点,而且根节点和其他点的差值不大于d,暴力统计个数就行。。

权值相同的点可能会有重复,所以加一个标记,当权值相等时看有没有这个标记。

#include<cstdio>#include<cstring>#include<algorithm>#define ll __int64using namespace std;const int MAXN=2010;const int MOD=1e9+7;struct EDGE{int v,next;}edge[MAXN<<1];int head[MAXN],size;bool vis[MAXN];void init(){memset(head,-1,sizeof(head));size=0;}void add_edge(int u,int v){edge[size].v=v;edge[size].next=head[u];head[u]=size++;}int val[MAXN];int d,n;ll dfs(int u,int fa,int c){int i;ll sum=1;for(i=head[u];i!=-1;i=edge[i].next){int v=edge[i].v;if(val[v]>c)continue;if(v==fa)continue;if(c-val[v]>d)continue;if(val[v]==c&&vis[v])continue;sum=sum*dfs(v,u,c)%MOD;}return sum+1;}int main(){int i;while(scanf("%d%d",&d,&n)==2){for(i=1;i<=n;i++)scanf("%d",&val[i]);int u,v;init();for(i=1;i<n;i++){scanf("%d%d",&u,&v);add_edge(u,v);add_edge(v,u);}memset(vis,0,sizeof(vis));ll ans=0;for(i=1;i<=n;i++){ans--;ans=(ans+dfs(i,-1,val[i]))%MOD;vis[i]=1;}printf("%I64d\n",ans);}return 0;}



0 0
原创粉丝点击