试题及测试数据:http://share.weiyun.com/3d36269336a370289b5a780bc640a215
总结:
T1 稍微有点贪心的模拟(具体操作见代码)
T2 分别以(1,2)建立一个等差数列a,再又剩下去组成等差数列b
(1,3)、(2,3)同理;
如果三种情况都不能匹配完所有元素,即为No Solution ;
否则输出答案即可;
T3 只会dfs 30分
T1代码(100分)
#include<cstdio> #include<algorithm> using namespace std; const int N=1e5+10; struct node{ int w,id,b; }a[N]; char s[N]; int n,m,w[N],vis[N]; int ans=0x3f3f3f3f; inline bool cmp(const node &a,const node &b){//定义优先级 if(a.w==b.w&&a.b!=b.b) return a.b>b.b;//相同条件下,-比+更有 if(a.w==b.w&&a.b==b.b){ if(a.b==2) return a.id<b.id;//-改前面的 else return a.id>b.id;//+改后面的 } return a.w<b.w;//第一关键:绝对值之差 } void solve(){ for(int i=0;i<=9;i++){//总共十种情况 if(vis[i]){//能否向i这个数字靠拢 for(int j=1;j<=n;j++){ a[j].id=j; a[j].w=abs(s[j]-i); a[j].b=s[j]>=i?2:1;//2为-,1为+ } sort(a+1,a+n+1,cmp); int tot=0; for(int j=1;j<=m;j++) tot+=a[j].w;//本次方案的花费 if(tot<ans){ ans=tot; for(int j=1;j<=n;j++) w[j]=s[j];//复制原来的 for(int j=1;j<=m;j++) w[a[j].id]=i;//改上要改的(当前最优) } } } } int main(){ freopen("number.in","r",stdin); freopen("number.out","w",stdout); scanf("%d%d%s",&n,&m,s+1); for(int i=1;i<=n;i++) s[i]-='0',vis[s[i]]++;//统计ing solve(); printf("%d ",ans); for(int i=1;i<=n;i++) printf("%d",w[i]); return 0; }
T2代码(30分)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; inline const int read(){ register int x=0,f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } const int N=1e5+10; int n,cnt,d,sum[N],a[N]; int a1[N],a2[N]; bool vis[N]; int main(){ //freopen("sh.txt","r",stdin); freopen("progression.in","r",stdin); freopen("progression.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); a1[++a1[0]]=a[1]; a1[++a1[0]]=a[2]; d=a1[2]-a1[1]; vis[1]=vis[2]=1; for(int i=3;i<=n;i++) if(!vis[i]){ if(a[i]-a1[a1[0]]==d){ a1[++a1[0]]=a[i]; vis[i]=1; } } if(a1[0]==2){ a1[a1[0]]=a[3]; d=a1[2]-a1[1]; vis[2]=0;vis[3]=1; for(int i=3;i<=n;i++) if(!vis[i]){ if(a[i]-a1[a1[0]]==d){ a1[++a1[0]]=a[i]; vis[i]=1; } } } for(int i=2,tot=1;tot<=2&&i<=n;i++){ if(!vis[i]){ a2[++a2[0]]=a[i]; vis[i]=1; tot++; } } d=a2[2]-a2[1]; for(int i=2;i<=n;i++) if(!vis[i]){ if(a[i]-a2[a2[0]]==d){ a2[++a2[0]]=a[i]; vis[i]=1; } } if(a1[0]+a2[0]<n){ memset(vis,0,sizeof vis); a1[1]=a[2]; a1[a1[0]=2]=a[3]; d=a1[2]-a1[1]; vis[1]=0; vis[2]=vis[3]=1; for(int i=3;i<=n;i++) if(!vis[i]){ if(a[i]-a1[a1[0]]==d){ a1[++a1[0]]=a[i]; vis[i]=1; } } a2[0]=0; for(int i=1,tot=1;tot<=2&&i<=n;i++){ if(!vis[i]){ a2[++a2[0]]=a[i]; vis[i]=1; tot++; } } d=a2[2]-a2[1]; for(int i=1;i<=n;i++) if(!vis[i]){ if(a[i]-a2[a2[0]]==d){ a2[++a2[0]]=a[i]; vis[i]=1; } } } if(a1[0]+a2[0]<n) puts("No solution"); else{ printf("%d ",a1[0]); for(int i=1;i<=a1[0];i++) printf("%d ",a1[i]); putchar(' '); printf("%d ",a2[0]); for(int i=1;i<=a2[0];i++) printf("%d ",a2[i]); } return 0; }
T3代码(30分)
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; inline const int read(){ register int x=0,f=1; register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } const int N=1e5+10; pair<int,int>at[N]; struct node{ int v,next; }e[N<<1]; int n,m,cas,tot,head[N]; bool vis[N],b[N<<1]; void add(int x,int y){ e[++tot].v=y; e[tot].next=head[x]; head[x]=tot; } void bfs(int S){ queue<int>q; q.push(S); vis[S]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=head[x];i;i=e[i].next){ if(b[i]) continue; int v=e[i].v; if(!vis[v]){ vis[v]=1; q.push(v); } } } } int main(){ freopen("network.in","r",stdin); freopen("network.out","w",stdout); n=read();m=read(); for(int i=1,x,y;i<=m;i++){ x=read();y=read();add(x,y); at[i]=make_pair(x,y); } for(int i=1,x,y;i<=m;i++) add(at[i].second,at[i].first); cas=read(); for(int x,y,tot=0;cas--;tot=0){ x=read();y=read(); memset(b,0,sizeof b); memset(vis,0,sizeof vis); for(int i=x;i<=y;i++) b[i]=1,b[i+m]=1;; for(int i=1;i<=n;i++) if(!vis[i]){ bfs(i); tot++; } printf("%d ",tot); } return 0; }