mNOIP 模拟赛 Day 2

来源:互联网 发布:易语言写软件 编辑:程序博客网 时间:2024/06/07 05:50

t1

题目背景

pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv

丹青千秋酿,一醉解愁肠。
无悔少年枉,只愿壮志狂。
题目描述

小 F 很喜欢数学,但是到了高中以后数学总是考不好。

有一天,他在数学课上发起了呆;他想起了过去的一年。一年前,当他初识算法竞赛的 时候,觉得整个世界都焕然一新。这世界上怎么会有这么多奇妙的东西?曾经自己觉得难以 解决的问题,被一个又一个算法轻松解决。

小 F 当时暗自觉得,与自己的幼稚相比起来,还有好多要学习的呢。

一年过去了,想想都还有点恍惚。

他至今还能记得,某天晚上听着入阵曲,激动地睡不着觉,写题写到鸡鸣时分都兴奋不 已。也许,这就是热血吧。

也就是在那个时候,小 F 学会了矩阵乘法。让两个矩阵乘几次就能算出斐波那契数列的 第 10^{100}10
100
项,真是奇妙无比呢。

不过,小 F 现在可不想手算矩阵乘法——他觉得好麻烦。取而代之的,是一个简单的小 问题。他写写画画,画出了一个 n \times mn×m 的矩阵,每个格子里都有一个不超过 kk 的正整数。

小 F 想问问你,这个矩阵里有多少个不同的子矩形中的数字之和是 kk 的倍数? 如果把一个子矩形用它的左上角和右下角描述为 (x_1,y_1,x_2,y_2)(x
1
​ ,y
1
​ ,x
2
​ ,y
2
​ ),其中x_1 \le x_2,y_1 \le y_2x
1
​ ≤x
2
​ ,y
1
​ ≤y
2
​ ; 那么,我们认为两个子矩形是不同的,当且仅当他们以 (x_1,y_1,x_2,y_2)(x
1
​ ,y
1
​ ,x
2
​ ,y
2
​ ) 表示时不同;也就是 说,只要两个矩形以 (x_1,y_1,x_2,y_2)(x
1
​ ,y
1
​ ,x
2
​ ,y
2
​ ) 表示时相同,就认为这两个矩形是同一个矩形,你应该 在你的答案里只算一次。

输入输出格式

输入格式:
从标准输入中读入数据。

输入第一行,包含三个正整数 n,m,kn,m,k。

输入接下来 nn 行,每行包含 mm 个正整数,第 ii 行第 jj 列表示矩阵中第 ii 行第 jj 列 中所填的正整数 a_{i,j}a
i,j
​ 。

输出格式:
输出到标准输出中。

输入一行一个非负整数,表示你的答案。

输入输出样例

输入样例#1: 复制
2 3 2
1 2 1
2 1 2
输出样例#1: 复制
6
说明

【样例 1 说明】

这些矩形是符合要求的: (1, 1, 1, 3),(1, 1, 2, 2),(1, 2, 1, 2),(1, 2, 2, 3),(2, 1, 2, 1),(2, 3, 2, 3)。

子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。

每个测试点的数据规模及特点如下表:

特殊性质:保证所有 a_{i,j}a
i,j
​ 均相同。

P3941 入阵曲
枚举行,每一列求余数,余数相同的之间区间就是k的倍数
优化为n^3

#include<cstdio>using namespace std;int n,m,a[410][410],s[410][410],K,cnt[1100000],b[410];long long ans;int main(){    scanf("%d%d%d",&n,&m,&K);    for(int i=1;i<=n;i++)     for(int j=1;j<=m;j++) scanf("%d",&a[i][j]),s[i][j]=(s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j])%K;    for(int i=1;i<=n;i++)    for(int j=i;j<=n;j++){        cnt[0]=1;        for(int k=1;k<=m;k++)        ans+=cnt[b[k]=((s[j][k]-s[i-1][k])%K+K)%K]++;        for(int k=1;k<=m;k++) cnt[b[k]]=0;     }    printf("%lld",ans);}

t2

题目背景

pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv

历史/落在/赢家/之手
至少/我们/拥有/传说
谁说/败者/无法/不朽
拳头/只能/让人/低头
念头/却能/让人/抬头
抬头/去看/去爱/去追
你心中的梦
题目描述

又想起了四月。

如果不是省选,大家大概不会这么轻易地分道扬镳吧? 只见一个又一个昔日的队友离开了机房。

凭君莫话封侯事,一将功成万骨枯。

梦里,小 F 成了一个给将军送密信的信使。

现在,有两封关乎国家生死的密信需要送到前线大将军帐下,路途凶险,时间紧迫。小 F 不因为自己的祸福而避趋之,勇敢地承担了这个任务。

不过,小 F 实在是太粗心了,他一不小心把两封密信中的一封给弄掉了。

小 F 偷偷打开了剩下的那封密信。他 发现一副十分详细的地图,以及几句批文——原来 这是战场周围的情报地图。他仔细看后发现,在这张地图上标记了 n 个从 1 到 n 标号的 驿站,n − 1 条长度为 1 里的小道,每条小道双向连接两个不同的驿站,并且驿站之间可以 通过小道两两可达。

小 F 仔细辨认着上面的批注,突然明白了丢失的信的内容了。原来,每个驿站都可以驻 扎一个小队,每个小队可以控制距离不超过 k 里的驿站。如果有驿站没被控制,就容易产 生危险——因此这种情况应该完全避免。而那封丢失的密信里,就装着朝廷数学重臣留下的 精妙的排布方案,也就是用了最少的小队来控制所有驿站。

小 F 知道,如果能计算出最优方案的话,也许他就能够将功赎过,免于死罪。他找到了 你,你能帮帮他吗? 当然,小 F 在等待你的支援的过程中,也许已经从图上观察出了一些可能会比较有用的 性质,他会通过一种特殊的方式告诉你。

输入输出格式

输入格式:
从标准输入中读入数据。

输入第 1 行一个正整数 n,k,t,代表驿站数,一支小队能够控制的最远距离,以及特 殊性质所代表的编号。关于特殊性质请参照数据范围。

输入第 2 行至第 n 行,每行两个正整数 u_iu
i
​ ,v_iv
i
​ ,表示在 u_iu
i
​ 和 v_iv
i
​ 间,有一条长度为 一里的小道。

输出格式:
输出到标准输出中。

输出一行,为最优方案下需要的小队数。

输入输出样例

输入样例#1: 复制
4 1 0
1 2
1 3
1 4
输出样例#1: 复制
1

输入样例#2: 复制
6 1 0
1 2
1 3
1 4
4 5
4 6
输出样例#2: 复制
2
说明

【样例 1 说明】

如图。由于一号节点到周围的点距离均是 1,因此可以控制所有驿站。

【样例 2 说明】

如图,和样例 1 类似。

子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。

关于 t 的含义如下: t = 0:该测试点没有额外的特殊性质; t = 1:保证最多 8 个点的所连接的小道超过 1 条; t = 2:保证所有点到 1 号点的距离不超过 2。

每个测试点的数据规模及特点如下表

洒水题,从深度最低的贪,将上面的距离为k的删掉,找深度最深的点,o(n*k)

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int M=110000,inf=1e9+7;struct st{    int s,id;    inline bool operator<(const st &b)const{        return s>b.s;    }}tmp[M];int n,K,tot,cnt,h[M],nex[M*2],to[M*2],ans,vis[M],dep[M],t,vis2[M];void add(int x,int y){    nex[++tot]=h[x];    to[tot]=y;    h[x]=tot;}void dfs(int x,int k,int fa){    if(k>=inf)tmp[++cnt].s=dep[x],tmp[cnt].id=x;    else vis2[x]=1;    if(k>=2*K&&k<inf) return ;    for(int i=h[x];i;i=nex[i]){        if(to[i]==fa) continue;        dep[to[i]]=dep[x]+1;        dfs(to[i],k+1,x);    }}int main(){    scanf("%d%d%d",&n,&K,&t);    for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);//dep[1]=1;    dfs(1,inf,1);    sort(tmp+1,tmp+cnt+1);    for(int i=1;i<=cnt;i++){        if(!vis2[tmp[i].id])        dfs(tmp[i].id,0,tmp[i].id),ans++;    }    printf("%d",ans);}
原创粉丝点击