这次打得较差,差点就绿了。。。
B题,这B题竟然WA了,再看看就发现一个很严重的错误。。--!
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int num[3050];
int main(){
int n;
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d",&num[i]);
}
sort(num,num+n);
int cnt=0,ans=0;
for(int i=1;i<n;i++){
if(num[i]==num[i-1]){
cnt++;
}
else {
int k=num[i]-num[i-1]-1;
if(k>=cnt){
ans=ans+(1+cnt)*cnt/2;
cnt=0;
}
else{
ans=ans+(1+k)*k/2;
cnt-=k;
}
ans=ans+cnt*(k+1);
}
}
if(cnt>0){
ans=ans+(1+cnt)*cnt/2;
}
printf("%d\n",ans);
}
return 0;
}
D题,可以预处理出各个数个含的质数的个数,可以用循环处理,求前缀和。循环是,从2开始,d记录下它有没有质因子,d=0则证明它当前是素数,第二层对j=i*k这样的数求它含有i的个数。如果d不为0,说明它不是素数,且由于一直循环,所以处理到它时就是已经把它所有质因子个数算出来了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
const int N=5000000;
int d[N+10];
int s[N+10];
void initial(){
memset(d,0,sizeof(d));
s[0]=s[1]=0;
for(int i=2;i<=N;i++){
if(d[i]==0){
d[i]++;
for(int j=i+i;j<=N;j+=i){
int c=j;
while(c%i==0){
d[j]++;
c/=i;
}
}
}
s[i]=s[i-1]+d[i];
}
}
int main(){
initial();
int T,a,b;
scanf("%d",&T);
while(T--){
scanf("%d%d",&a,&b);
printf("%d\n",s[a]-s[b]);
}
return 0;
}
E题,二分图网络流
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
/*
这道在开始也在想网络流,但是,看到只能移动一条边时,就无语了。。群里一讨论,对哦,二分图拆点建边,
这样就是一条边了。。。T_T我果然是渣。。 s->i建一条a[i]的边,i+n->e建一条b[i]的边。u-v就按u->v‘,v->u‘。
注意加上u->u‘
*/
const int INF=0x3f3f3f3f;
const int MAXN=300;//点数的最大值
const int MAXM=2000;//边数的最大值
struct Node
{
int from,to,next;
int cap;
}edge[MAXM];
int tol;
int dep[MAXN];//dep为点的层次
int head[MAXN];
int flow[MAXN][MAXN];
int n,m;
void init()
{
tol=0;
memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)//第一条变下标必须为偶数
{
edge[tol].from=u;
edge[tol].to=v; edge[tol].cap=w; edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].next=head[v];
head[v]=tol++;
}
int BFS(int start,int end)
{
int que[MAXN];
int front,rear; front=rear=0;
memset(dep,-1,sizeof(dep));
que[rear++]=start;
dep[start]=0;
while(front!=rear)
{
int u=que[front++];
if(front==MAXN)front=0;
for(int i= head[u];i!=-1; i=edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap>0&& dep[v]==-1)
{
dep[v]=dep[u]+1;
que[rear++]=v;
if(rear>=MAXN) rear=0;
if(v==end)return 1;
}
}
}
return 0;
}
int dinic(int start,int end)
{
int res=0;
int top;
int stack[MAXN];//stack为栈,存储当前增广路
int cur[MAXN];//存储当前点的后继
while(BFS(start,end))
{
memcpy(cur,head, sizeof(head));
int u=start;
top=0;
while(1)
{
if(u==end) //到达汇点
{
int min=INF;
int loc;
for(int i=0;i<top;i++)
if(min>edge[stack[i]].cap)
{
min=edge[stack[i]].cap;
loc=i;
}
for(int i=0;i<top;i++){
edge[stack[i]].cap-=min;
edge[stack[i]^1].cap+=min;
}
res+=min;
top=loc; // 以最小边的起点为源点再寻找其他增广路径
u=edge[stack[top]].from;
}
for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next) //寻找可增广的路径,即确定edge[]中以u为起点可增广的i的第一条边的位置
if(edge[i].cap!=0 && dep[u]+1==dep[edge[i].to])
break;
if(cur[u]!=-1)
{
stack [top++]=cur[u];
u=edge[cur[u]].to;
}
else
{
if(top==0) break; //不能再增广
dep[u]=-1;
u= edge[stack [--top] ].from; //退栈寻找下一条
}
}
}
return res;
}
int bef[MAXN],aft[MAXN];
int main(){
int s,e;
while(scanf("%d%d",&n,&m)!=EOF){
init();
int sum=0; s=0; e=2*n+1;
memset(flow,0,sizeof(flow));
for(int i=1;i<=n;i++){
scanf("%d",&bef[i]);
sum+=bef[i];
}
int cp=sum;
for(int i=1;i<=n;i++){
scanf("%d",&aft[i]);
sum-=aft[i];
}
for(int i=1;i<=n;i++){
addedge(s,i,bef[i]);
addedge(i+n,e,aft[i]);
addedge(i,i+n,INF);
}
int u,v;
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
addedge(u,v+n,INF);
addedge(v,u+n,INF);
}
if(sum!=0){
printf("NO");
}
else{
int res=dinic(s,e);
if(res!=cp){
puts("NO");
}
else{
puts("YES");
for(int i=n+1;i<=2*n;i++){
int v=i-n;
for(int ei=head[i];ei!=-1;ei=edge[ei].next){
int u=edge[ei].to;
if(u<e){
flow[u][v]=edge[ei].cap;
}
}
}
for(int i=1;i<=n;i++){
printf("%d",flow[i][1]);
for(int j=2;j<=n;j++)
printf(" %d",flow[i][j]);
printf("\n");
}
}
}
}
}
Codeforces Round #304 (Div. 2)
原文:http://www.cnblogs.com/jie-dcai/p/4523897.html