纪中2020.4.4普及C组模拟赛总结

题太难了,唉

T1

本题我打了个暴力,错了。

正解:暴力
每次调换位置,不用管此时在这个位置上的数,只要得出进行 M 次操作后第 i 位会换到的位置并标记,每一轮结束后就只用调位置就行了。

A C   C o d e AC~Code AC Code

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int l,r,a[100010],b[100010],c[100010];
int n,m,k;
int main()
{
    freopen("swap.in","r",stdin);
    freopen("swap.out","w",stdout);
    cin>>n>>m>>k;
    for(int i=1; i<=n; i++)
       a[i]=i;
    for(int i=1; i<=m; i++)
	 {
	 	scanf("%d %d",&l,&r);
        for(int i=l; i<=r; i++)   //存l~r的a[i]的取反
           b[i]=a[l+r-i];
        for(int i=l; i<=r; i++)   //取反
           a[i]=b[i];
     }
    for(int i=1; i<=n; i++)  //赋初值
	 {
        c[i]=a[i];
        a[i]=i;
     }
    while(k>0)
	 {
        if(k&1)
		 {
            for(int i=1; i<=n; i++)
               a[i]=c[a[i]];
         }
        for(int i=1; i<=n; i++)  //按位置放
           b[i]=c[c[i]];
        for(int i=1; i<=n; i++)
           c[i]=b[i];
        k/=2;
     }
    for(int i=1; i<=n; i++)
       printf("%d\n",a[i]);
	return 0;
}

T2

在这里插入图片描述
A C   C o d e AC~Code AC Code

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
long long he[100010],js[100010],v[100010];
long long s[100010],y[100010],x[100010];
long long ans,n;
struct node
{
    long long x,y;
}a[100010];
bool cmp1(const node&l,const node&r)
{
    if(l.x!=r.x)
      return l.x<r.x;
    return l.y<r.y;
}
bool cmp2(const node&l,const node&r)
{
    if(l.x!=r.x)
      return l.x>r.x;
    return l.y>r.y;
}
bool cmp3(const node&l,const node&r)
{
    if(l.x!=r.x)
      return l.x<r.x;
    return l.y>r.y;
}
bool cmp4(const node&l,const node&r)
{
    if(l.x!=r.x)
      return l.x>r.x;
    return l.y<r.y;
}
void pd()
{
    memset(he,0,sizeof(he));
    memset(js,0,sizeof(js));
    memset(v,0,sizeof(v));
    memset(s,0,sizeof(s));
    for(long long i=1; i<=n; i++)
     {
        long long xx=a[i].x,yy=a[i].y;
        he[xx]=(he[xx]+abs(yy-y[xx])*v[xx])%1000000007;
        y[xx]=yy,v[xx]++;  //往左往右枚举
        js[yy]=(js[yy]+abs(xx-x[yy])*s[yy])%1000000007;
        x[yy]=xx,s[yy]++;
        ans=(ans+he[xx]*js[yy])%1000000007;
     }
}
int main()
{
    freopen("triangles.in","r",stdin);
    freopen("triangles.out","w",stdout);
    cin>>n;
    for(int i=1; i<=n; i++)
     {
        cin>>a[i].x>>a[i].y;
        a[i].x+=10005;
        a[i].y+=10005;
     }
    sort(a+1,a+1+n,cmp1);   //同样的事情做四次
    pd();
    sort(a+1,a+1+n,cmp2);
    pd();
    sort(a+1,a+1+n,cmp3);
    pd();
    sort(a+1,a+1+n,cmp4);
    pd();
    cout<<ans;
	return 0;
}

T3

此题枚举
我们枚举每一个房间,找与它相连的房间。
不停地在房间来回走,
直到除了枚举的房间以外其余房间都是 12 12 12
根(就是枚举的第一个房间) 正好是 12 12 12或是 1 1 1的时候就证明这条路是可以的,
那为啥 1 1 1可以呢?
因为可以在根的最后一个孩子停下,不走回来。
这时候根和最后一个孩子的时间会差一个

A C   C o d e AC~Code AC Code

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,x,y,ans,a[10010],t[10010];
int head[10010],tot;
struct node
{
	int x,y,next;
}e[10010];
void ljb(int x,int y)
{
	e[++tot].x=x;
	e[tot].y=y;
	e[tot].next=head[x];
	head[x]=tot;
}
void dfs(int x,int y)
{
	for(int i=head[x]; i; i=e[i].next)
	 {
		if(e[i].y==y)   //防止死循环
		  continue; 
		dfs(e[i].y,x);
		t[x]=(t[x]-t[e[i].y]+12)%12;  //钟表+1(因为我们是这样枚举的,所以12就是0)
	}	
}
int main()
{
	freopen("clocktree.in","r",stdin);
    freopen("clocktree.out","w",stdout);
	cin>>n;
	for(int i=1; i<=n; i++)
	   scanf("%d",&a[i]),a[i]%=12;
	for(int i=1; i<=n-1; i++)
	 {
		scanf("%d%d",&x,&y);
		ljb(x,y);
		ljb(y,x);
	 }
	for(int i=1; i<=n; i++)
	 {
		memcpy(t,a,sizeof(t));
		dfs(i,0);
		if(t[i]==0||t[i]==1)  //判断是否可以(这里0就是12)
		  ans++;
	 }
	cout<<ans;
	return 0;
}

总分

0 + 10 + 6.7 = 16.7 p t s 0+10+6.7=16.7pts 0+10+6.7=16.7pts

抽空学一学新知识吧!
(纪六三人 A K AK AK我佛了)

现已全对
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值