牛客小白月赛11 题解

A签到题

链接:https://ac.nowcoder.com/acm/contest/370/A
来源:牛客网
 

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

恭喜你找到了本场比赛的签到题!
为了让大家都有抽奖的机会,只需要复制粘贴以下代码(并且稍微填下空)即可 AC:
(我超良心的)

#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #define fi first
 #define lc (x<<1)
 #define se second
 #define U unsigned
 #define rc (x<<1|1)
 #define Re register
 #define LL long long
 #define MP std::make_pair
 #define CLR(i,a) memset(i,a,sizeof(i))
 #define FOR(i,a,b) for(Re int i = a;i <= b;++i)
 #define ROF(i,a,b) for(Re int i = a;i >= b;--i)
 #define SFOR(i,a,b,c) for(Re int i = a;i <= b;i+=c)
 #define SROF(i,a,b,c) for(Re int i = a;i >= b;i-=c)
 #define DEBUG(x) std::cerr << #x << '=' << x << std::endl
 const int MAXN = 1000000+5;
 struct Line{
     int l,r;
     bool operator < (const Line &other) const {
         return l < other.l && r < other.r;
     }
 };
 int N,maxL;
 std::set L;
 inline int calc(){
     // 返回 set 中所有线段的并长度。
 }
 int main(){
     scanf("%d%d",&N,&maxL);
     while(N--){
         int opt,x,y;
         scanf("%d%d%d",&opt,&x,&y);
         if(opt == 1){
             if(L.find((Line){x,y}) != L.end()) continue;
             L.insert((Line){x,y});
         }
         if(opt == 2){
             if(L.find((Line){x,y}) == L.end()) continue;
             L.erase((Line){x,y});
         }
         if(opt == 3){
             printf("%d\n",calc());
         }
     }
     return 0;
 }

输入描述:

第一行两个整数 N,L,意义如代码所述。

接下来 N 行,每行三个整数 opt,l,r,意义如代码所述。

输出描述:

对于每一组 opt=3 的询问输出一个答案。

示例1

输入

复制

6 13
1 1 2
1 4 5
1 4 7
1 6 9
1 12 13
3 3 3

输出

复制

10

说明

我们依次加入线段[1,2],[4,5],[4,7],[6,9],[12,13], 它们的并集长度为 10.

备注:

N≤105,L≤105,0≤l≤r≤LN≤105,L≤105,0≤l≤r≤L,保证数据随机生成。

分析:

这个签到题出的有毒,其实自己写一个暴力就能过,那个重载真是恶心人。

线段树可以优化一下

#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 const int MAXN = 1000000+5;
 struct Line{
     int l,r;
     bool operator < (const Line &other) const {
         if(l!=other.l)
         return l < other.l;
         return r L;
 int s[100010];
 inline int calc(){
     int sum=0;
     for(int i=1;i<=maxL;i++)
        if(s[i])sum++;
     return sum;// 返回 set 中所有线段的并长度。
 }
 int main(){
     scanf("%d%d",&N,&maxL);
     while(N--){
         int opt,x,y;
         scanf("%d%d%d",&opt,&x,&y);
         if(opt == 1){
             if(L.find((Line){x,y}) != L.end()) continue;
             L.insert((Line){x,y});
             for(int i=x;i<=y;i++)
                s[i]++;
         }
         if(opt == 2){
             if(L.find((Line){x,y}) == L.end()) continue;
             L.erase((Line){x,y});
              for(int i=x;i<=y;i++)
                s[i]--;
         }
         if(opt == 3){
             printf("%d\n",calc());
         }
     }
     return 0;
 }

 

 

C Rinne Loves Study

链接:https://ac.nowcoder.com/acm/contest/370/C
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Rinne 喜欢使用一种奇怪的方法背单词,现在这些单词被放在了一个 n×mn×m 的格子里。由于背单词是一个令人烦躁的事情,所以她决定每天只背同一行或者同一列的单词。她一共会背 T 次单词,为了方便巩固,她现在想知道:对于每个单词,最后一次背是什么时候呢?
她这么可爱当然会算啦!但是她想考考你。

输入描述:

第一行三个整数 n,m,T。
接下来 T 行,第 i+1 行描述第 i 天干了什么,每行的格式如下:
`1 x`:说明她在这一天背了第 x 行的单词;
`2 y`说明她在这一天背了第 y 列的单词。
输入的所有量的具体意义请参考「题目描述」。

输出描述:

输出一个 n×mn×m 的矩阵 a,ai,jai,j 表示第 i 行第 j 列这个单词最后一次被背诵是在第几天。

示例1

输入

复制

3 3 3
1 2
2 3
1 3

输出

复制

0 0 2
1 1 2
3 3 3

备注:

n×m≤105,T≤105

分析:思维题。

开1e5*1e5会爆内存,需要点四维转换,可以开两个数组a,b,a[i]表示第i行的背的第几天,,b[i]表示第i列的背的第几天,

因为会覆盖,天数越大越优先,所以最后要求的i行j列的背的最后天数为max(a[i],b[j])

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll;
using namespace std;
int a[100005],b[100005];
int main()
{
	 int n,m,T;
	 scanf("%d%d%d",&n,&m,&T);
	 
	 for(int i=1;i<=T;i++)
	{
	  int op,u;
	  scanf("%d%d",&op,&u);
	  if(op==1)
	   a[u]=i;
	  else
	  {
	  	b[u]=i;
	  }
	} 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
			{
				
				printf("%d ",max(a[i],b[j]));
			}
			printf("\n")  ;
	}
     return 0;
}

J Rinne Loves Math

链接:https://ac.nowcoder.com/acm/contest/370/J
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Rinne 刚刚学习了最简二次根式,于是她想用程序实现一个。
为了简化问题,在本题中,最简二次根式 a√bab 的定义为:
不存在b的一个因子k s.t. ∃x∈N∗,x2=k不存在b的一个因子k s.t. ∃x∈N∗,x2=k
即根号下的数字不含平方数因子。
举个最简二次根式的例子:√5,√200501175,20050117
举个不是最简的例子:√20,√44420,444
现在 Rinne 给了你形如 √nn 的式子中的 n,让你输出化简后的结果 a√bab 中的 a,b,如果这样的式子在实数范围内没有意义,输出 -1。

输入描述:

第一行一个整数 T,表示数据组数。
接下来 T 行,每行一个整数 x 表示根号下的数。

输出描述:

输出一共 T 行,每行两个数表示 √xx  化简后的答案 a,b

示例1

输入

复制

4
20
25
-2005
11

输出

复制

2 5
5 1
-1
1 11

说明

20=4×520=4×5
25=5×525=5×5
实数范围内 √nn中 n 小于 0 没有意义。
11 是个质数。

备注:

T≤100,0<|x|≤107

分析:水题

预处理一下所有数的平方,然后逐个判断

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll;
using namespace std;
const int N=10000005 ;
ll a[10000005];
int main()
{
	 int m,T;
	 ll n;
	 scanf("%d",&T);
	 for(int i=1;i<=N;i++)
	 {
	 	a[i]=i*i;
	 }
	 while(T--)
	 {
	 	scanf("%lld",&n);
	 	if(n<0)
	 	{
	 		printf("-1\n");
	 		continue;
	 	}	
	 	int l=1,r=sqrt(n);
		for(int i=r+1;i>=1;i--)
		{
			//cout<<" "<

其他的题没看,所以附上答案:

你可能感兴趣的:(比赛题解,牛客网题解)