﻿ CCF模拟题-201909

## 2.小明种苹果（续）（100分）

```#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1010
using namespace std;
int n,op,x,m,a[maxn];
long long sum;
bool vis[maxn];
int main(){
//freopen("Cola.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&m);
int ansnow;
scanf("%d",&ansnow);
a[i]=ansnow;
for(int j=1;j<m;j++){
scanf("%d",&x);
if(x>0){
if(x!=a[i])vis[i]++;
a[i]=x;
}
else a[i]+=x,ansnow=a[i];
}
sum+=a[i];
}
printf("%lld ",sum);
sum=0;
for(int i=1;i<=n;i++)sum+=vis[i];
printf("%lld ",sum);
sum=0;
for(int i=2;i<=n-1;i++){
if(vis[i]&&vis[i-1]&&vis[i+1])sum++;
}
if(n>=3){
if(vis[1]&&vis[2]&&vis[n])sum++;
if(vis[n]&&vis[n-1]&&vis[1])sum++;
}
printf("%lld
",sum);
return 0;
}```

## 3.字符画（0分）

```#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,len[1930][1090],color[1930][1090][4],num,p,q;
char colors[1930][1090][4][5];
char s[1930][1090][10];
int change(char c1,char c2){
int a=0,b=0;
if(c1>='0'&&c1<='9')a=c1-'0';
else a=c1-'A'+10;
if(c2>='0'&&c2<='9')b=c2-'0';
else b=c2-'A'+10;
return a*16+b;
}
bool check1(int i,int j){
if(i==1&&j==1)return 1;
int prei=i,prej=j;
if(j==1){
prei--;
prej=m-q+1;
}
else prej--;
for(int k=1;k<=3;k++){
if(color[i][j][k]!=color[prei][prej][k])return 1;
}
return 0;
}
void solve(){
for(int i=1;i<=n;i+=p){
for(int j=1;j<=m;j+=q){
if(check1(i,j)){//是否新建色块
if(i!=1||j!=1){//将之前的修改屏蔽
printf("\x1B\x5B\x30\x6D");//ESC[0m
}
printf("\x1B\x5B\x34\x38\x3B\x32");//          ------------------------ESC[48;2
for(int k=1;k<=3;k++){
printf("\x3B");//                               ------------------------;R;B;G
//                    printf("%s",colors[i][j][k]);//;R;B;G
if(colors[i][j][k][0]!='0'){
int x=colors[i][j][k][0];
if(x>=48&&x<=57){//这一位数为0~9
printf("\x%d",30+x-'0');
}
else {
printf("\x%d",41+x-'A');//这一位数为A~F
}
}
int x=colors[i][j][k][1];
if(x>=48&&x<=57){//这一位数为0~9
printf("\x%d",30+x-'0');
}
else {
printf("\x%d",41+x-'A');//这一位数为A~F
}
}
printf("\x6D");//                                   -------------------------m
}
printf("\x20");//                                       -------------------------当前色块对应的空格
if(i==n-p+1&&j==m-q+1){
printf("\x1B\x5B\x30\x6D");//ESC[0m
}
if(j==m-q+1){//行末
printf("\x0A");//回车
}
}
}
}
void change_to_char(int i,int j,int k,int x){
/*colors[i][j][k][0]='\';
colors[i][j][k][1]='x';
int a=x%16,b=x/16;
if(b<=9)colors[i][j][k][2]=b+'0';
else if(b>=10)colors[i][j][k][2]=b-10+'A';
if(a<=9)colors[i][j][k][3]=a+'0';
else if(a>=10)colors[i][j][k][3]=a-10+'A';*/
int a_num=x%16,b_num=x/16;
char a_s,b_s;
if(a_num<=9)a_s=a_num+'0';
else if(a_num>=10)a_s=a_num-10+'A';
if(b_num<=9)b_s=b_num+'0';
else if(b_num>=10)b_s=b_num-10+'A';
colors[i][j][k][0]=b_s;
colors[i][j][k][1]=a_s;
}
int main(){
freopen("Cola.txt","r",stdin);
/*printf("33[38;2;255;0;0mHello33[0m 33[38;2;0;0;255m33[48;2;255;255mWorld33[0m
");*/
scanf("%d%d",&m,&n);
scanf("%d%d",&q,&p);num=p*q;//num为每个色块内的颜色个数,p行q列
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%s",s[i][j]+1);
len[i][j]=strlen(s[i][j]+1);
}
}

for(int i=1;i<=1+(n/p-1)*p;i+=p){
for(int j=1;j<=1+(m/q-1)*q;j+=q){
int a=0,b=0,c=0;
for(int x=i;x<=i+p-1;x++){
for(int y=j;y<=j+q-1;y++){
if(len[x][y]==4){//对应#abc的情况
a+=change(s[x][y][2],s[x][y][2]);
b+=change(s[x][y][3],s[x][y][3]);
c+=change(s[x][y][4],s[x][y][4]);
}
else if(len[x][y]==2){//对应#a的情况
a+=change(s[x][y][2],s[x][y][2]);
b+=change(s[x][y][2],s[x][y][2]);
c+=change(s[x][y][2],s[x][y][2]);
}
else{
a+=change(s[x][y][2],s[x][y][3]);
b+=change(s[x][y][4],s[x][y][5]);
c+=change(s[x][y][6],s[x][y][7]);
}
}
}
color[i][j][1]=a/num;
color[i][j][2]=b/num;
color[i][j][3]=c/num;
}
}
for(int i=1;i<=n;i+=p){
for(int j=1;j<=m;j+=q){
for(int k=1;k<=3;k++)
change_to_char(i,j,k,color[i][j][k]);
//            printf("(%d,%d,%d) ",color[i][j][1],color[i][j][2],color[i][j][3]);
}
//        puts("");
}
/*for(int i=1;i<=n;i+=p){
for(int j=1;j<=m;j+=q){
printf("(%d,%d,%d) ",color[i][j][1],color[i][j][2],color[i][j][3]);
}
puts("");
}*/
solve();
}
/*
2 2
1 1
#010203
#2B675A
#234
#2
*/```

## 4.推荐系统（20分）

```/*
离线操作，把编号离散化
用mark标记某类的某个编号的东西还是否存在，来完成添加和删除功能
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,num,op_num,mx,idx[200010],cnt,tmp[60][130010];
struct node{
int type,sc,id;
}a[6500100];
struct Operator{
int op,type,id,sc;
int k[60];
}ope[100010];
int f(int x){//从大数映射到小数
return lower_bound(idx+1,idx+cnt+1,x)-idx;
}
bool mark[60][130010];
bool cmp(node x,node y){
if(x.sc!=y.sc)return x.sc>y.sc;
else if(x.type!=y.type)return x.type<y.type;
else return x.id<y.id;
}
int main(){
freopen("Cola.txt","r",stdin);
scanf("%d%d",&m,&n);
int id,sc;
for(int i=1;i<=n;i++){
scanf("%d%d",&id,&sc);
idx[++cnt]=id;
for(int j=1;j<=m;j++){
num++;
a[num].type=j;
a[num].sc=sc;
a[num].id=id;
}
}
scanf("%d",&op_num);
for(int i=1;i<=op_num;i++){
scanf("%d",&ope[i].op);
if(ope[i].op==1){
scanf("%d%d%d",&ope[i].type,&ope[i].id,&ope[i].sc);
idx[++cnt]=ope[i].id;
mx=max(mx,ope[i].id);
ope[i].type++;
}
else if(ope[i].op==2){
scanf("%d%d",&ope[i].type,&ope[i].id);
idx[++cnt]=ope[i].id;
mx=max(mx,ope[i].id);
ope[i].type++;
}
else{
scanf("%d",&ope[i].k[0]);
for(int j=1;j<=m;j++)scanf("%d",&ope[i].k[j]);
}
}
sort(idx+1,idx+cnt+1);
cnt=unique(idx+1,idx+cnt+1)-idx-1;
for(int i=1;i<=num;i++){
a[i].id=f(a[i].id);
mark[a[i].type][a[i].id]=1;
}

for(int i=1;i<=op_num;i++){
//        for(int i=1;i<=7;i++){for(int j=1;j<=2;j++){cout<<mark[j][i]<<' ';}cout<<endl;}cout<<endl;
if(ope[i].op==1){
num++;
a[num].type=ope[i].type;
a[num].id=f(ope[i].id);
a[num].sc=ope[i].sc;
mark[a[num].type][a[num].id]=1;
}
else if(ope[i].op==2){
mark[ope[i].type][f(ope[i].id)]=0;
}
else{
for(int j=1;j<=m;j++)tmp[j][0]=0;
sort(a+1,a+num+1,cmp);
int count=0;
for(int j=1;j<=num;j++){
if(!mark[a[j].type][a[j].id])continue;
else if(tmp[a[j].type][0]>=ope[i].k[a[j].type])continue;
else {
tmp[a[j].type][++tmp[a[j].type][0]]=idx[a[j].id];
count++;
if(count>=ope[i].k[0])break;
}
}
for(int j=1;j<=m;j++){
if(tmp[j][0]==0){
puts("-1");
continue;
}
else {
for(int k=1;k<=tmp[j][0];k++)
printf("%d ",tmp[j][k]);
puts("");
}
}
}
}
return 0;
}```

## 5.城市规划（20分）

```#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define maxn 50010
using namespace std;
struct node{
int to,pre,v;
}e[100010];
void Insert(int from,int to,int v){
e[++num].to=to;
e[num].v=v;
}
int dis[2010],d[20][20];
queue<int>q;
bool vis[maxn];
void bfs(int s){
q.push(s);
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
vis[s]=1;
while(!q.empty()){
int now=q.front();q.pop();
int to=e[i].to;
if(vis[to])continue;
vis[to]=1;
dis[to]=min(dis[to],dis[now]+e[i].v);
q.push(to);
}
}
}
void solve1(){
if(K<=1){
puts("0");
return;
}
int ans=0x7fffffff;
for(int i=1;i<=m;i++){
bfs(a[i]);
for(int j=i+1;j<=m;j++)
ans=min(ans,dis[a[j]]);
}
printf("%d
",ans);
}
void solve2(){
for(int i=1;i<=m;i++){
bfs(a[i]);
for(int j=1;j<=m;j++)
d[i][j]=dis[a[j]];
}
int ans=0x7fffffff,ans_now=0;
for(int sta=0;sta<(1<<m);sta++){
int sum=0;
for(int i=1;i<=m;i++)
if(sta&(1<<i-1))sum++;
if(sum!=K)continue;
ans_now=0;
for(int i=1;i<=m;i++){
if(!(sta&(1<<i-1)))continue;
for(int j=i;j<=m;j++){
if(!(sta&(1<<j-1)))continue;
ans_now+=d[i][j];
}
}
ans=min(ans,ans_now);
}
printf("%d
",ans);
return ;
}
int main(){
freopen("Cola.txt","r",stdin);
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=m;i++)scanf("%d",&a[i]);
int x,y,z;
for(int i=1;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
Insert(x,y,z);
Insert(y,x,z);
}
if(K<=2&&m>16){
solve1();
return 0;
}
else {
solve2();
return 0;
}
}```