第三届传智杯全国大学生IT技能大赛(决赛)B组--详细题解

2021-04-25 14:59:47 浏览数 (1)

思路:乱搞就行,就是统计同时存在两个数组里面的元素的个数。

代码语言:javascript复制
#include<bits/stdc  .h>
#define maxn 33
using namespace std;
int a[maxn],b[maxn];
int vis[maxn]={0};
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i  ){
		cin>>a[i];
		vis[a[i]]  ;
	}
	for(int i=1;i<=m;i  ){
		cin>>b[i];
		vis[b[i]]  ;
	}
	int ans = 0;
	for(int i=1;i<=22;i  ){
		if(vis[i] == 2) ans  ;
	}
	cout<<ans<<endl;
	return 0;
} 

思路:暴力去找就行。

代码语言:javascript复制
#include<bits/stdc  .h>
#define maxn 1002
using namespace std;

typedef long long ll;

ll a[maxn],b[maxn];

int main(){
	ll n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i  ){
		cin>>a[i];
	}
	sort(a 1,a n 1);
	ll ans = 0;
	for(int i=1;i<=n;i  ){
		for(int j=i 1;j<=n;j  ){
			if(a[i] * a[j] <= k) ans  ;
		}
	}
	cout<<ans<<endl;
	return 0;
}

思路:暴力每次截取一个子串去匹配。(先把字符串里面的字符都变成小写)

代码语言:javascript复制
#include<bits/stdc  .h>

using namespace std;

int main(){
	int t;
	cin>>t;
	while(t--){
		int len1,len2;
		string a,b;
		cin>>len1>>len2;
		cin>>a>>b;
		for(int i=0;i<len1;i  ){
			if(a[i] >= 'A' && a[i] <= 'Z'){
				a[i]  = 32;
			}
		}
		for(int i=0;i<len2;i  ){
			if(b[i] >= 'A' && b[i] <= 'Z'){
				b[i]  = 32;
			}
		}
		int ans = 0;
		//cout<<a<<" --" <<b<<endl;
		for(int i=0;i<len2 - len1   1;i  ){
			string s = b.substr(i,len1);
			if(s == a) ans   ;
		}
		cout<<ans<<endl;
	}
	return 0;
}

思路:我以为是博弈论呢,吓我一跳,就先去看E题了。最后交了几发随机函数。(我看成了打出比上个人大的牌,竟然还有限制条件!!!能打过的–最小的牌!!!

官方题解如下:

直接模拟即可,可以实现个函数 f(x,y)来查找当前这个人最小的满足比 y张 x 大的牌,先枚举一下 y 张牌的情况,从 x 1枚举,再枚举更多牌的情况。 判断有没有可以直接判断数量,只要对每个人记录一个 cnti 表示他第 i种牌有几张就可以快速判断,打出牌后要更新一下 cnti.

代码语言:javascript复制
#include<bits/stdc  .h>
using namespace std;
#define ll long long
#define db double
#define in inline
namespace fast_io
{
    char buf[1<<12],*p1=buf,*p2=buf,sr[1<<23],z[23],nc;int C=-1,Z=0,Bi=0,ny;
    in char gc() {return p1==p2&&(p2=(p1=buf) fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1  ;}
    in int read()
    {
        int x=0;ny=1;while(nc=gc(),(nc<48||nc>57)&&nc!=EOF)if(nc==45)ny=-1;Bi=1;if(nc<0)return nc;
        x=nc-48;while(nc=gc(),47<nc&&nc<58&&nc!=EOF)x=(x<<3) (x<<1) (nc^48),Bi  ;return x*ny;
    }
    in db gf() {int a=read(),y=ny,b=(nc!='.')?0:read();return (b?a (db)b/pow(10,Bi)*y:a);}
    in int gs(char *s) {char c,*t=s;while(c=gc(),c<=32);*s  =c;while(c=gc(),c>32)*s  =c;return s-t;}
    in void ot() {fwrite(sr,1,C 1,stdout);C=-1;}
    in void flush() {if(C>1<<22) ot();}
    template <typename T>
    in void write(T x,char t)
    {
        int y=0;if(x<0)y=1,x=-x;while(z[  Z]=x 48,x/=10);
        if(y)z[  Z]='-';while(sr[  C]=z[Z],--Z);sr[  C]=t;flush();
    }
    in void write(char *s) {int l=strlen(s);for(int i=0;i<l;i  )sr[  C]=*s  ;sr[  C]='n';flush();}
};
using namespace fast_io;
#define pii pair<int,int>
#define fi first
#define se second
const int N=1e3 5;
int n,m,a[4][N],c[4];
in pii ask(int x,pii y)
{
    for(int i=1;i<=n;i  ) for(int j=1;j<=m;j  ) 
    if(a[x][j]>=i&&(i>y.fi||(i==y.fi&&j>y.se))) return a[x][j]-=i,c[x]-=i,make_pair(i,j);
    return {-1,-1};
}
int main()
{
    n=c[1]=c[2]=c[3]=read(),m=read();
    for(int i=1;i<=3;i  ) for(int j=1;j<=n;j  ) a[i][read()]  ;
    for(int s=1,x,t;;s=t)
    {
        x=s,t=0;pii y={0,0};
        for(;x^t;x=x%3 1)
        {
            pii z=ask(x,y);
            if(!c[x]) return write(x,'n'),ot(),0;
            if(~z.fi) t=x,y=z;
        }
    }
    return ot(),0;
}

思路:我的思路是开一个multiset,然后每次二分找到第一个大于当前钱数的那个商品,然后指针往后移动一个,就是他能买起的最贴近的那个了。

TLE TLE TLE E题T了几次看榜单80 了,果断逃了(混不到奖品了呜呜呜)

TLE代码,大家可帮我康康。

代码语言:javascript复制
#include<bits/stdc  .h>
#define inf 0x3f3f3f3f 
#define maxn 100010
using namespace std;
typedef long long ll;
ll ans;
ll w[maxn],a[maxn];
multiset<ll> c;
bool vis[maxn]={0};
int main(){
	ll n,m;
	cin>>n>>m;
	ll maxx = -inf;
	for(int i=0;i<n;i  ){
		cin>>w[i];
		maxx = max(maxx,w[i]);
	}

	ll re;
	for(int i=0;i<m;i  ){
		cin>>re;//每件商品价格 
		if(re <= maxx) c.insert(re);
	}
	//对于每一个人去找最接近的 
	ans = 0;
	multiset<ll>::iterator res;
	for(int i=0;i<n;i  ){
		res = upper_bound(c.begin(),c.end(),w[i]);//找第一个大于w[i]的 
		res--;
	    if((res)!=c.end()){
	    	c.erase(res);
	        ans =1; 
		}
	}
	cout<<ans<<endl;
	return 0;
}

官方题解如下: 先将 w和 c 放一起排序,对于一个 c 中的元素是剩下的物品数加一,对于一个 w,若还有物品则物品数减一、答案加一,没有就不管。

仔细体会一下,感觉妙啊,自己是个XX。

代码语言:javascript复制
#include<bits/stdc  .h>
using namespace std;
#define ll long long
#define db double
#define in inline
namespace fast_io
{
    char buf[1<<12],*p1=buf,*p2=buf,sr[1<<23],z[23],nc;int C=-1,Z=0,Bi=0,ny;
    in char gc() {return p1==p2&&(p2=(p1=buf) fread(buf,1,1<<12,stdin),p1==p2)?EOF:*p1  ;}
    in int read()
    {
        int x=0;ny=1;while(nc=gc(),(nc<48||nc>57)&&nc!=EOF)if(nc==45)ny=-1;Bi=1;if(nc<0)return nc;
        x=nc-48;while(nc=gc(),47<nc&&nc<58&&nc!=EOF)x=(x<<3) (x<<1) (nc^48),Bi  ;return x*ny;
    }
    in db gf() {int a=read(),y=ny,b=(nc!='.')?0:read();return (b?a (db)b/pow(10,Bi)*y:a);}
    in int gs(char *s) {char c,*t=s;while(c=gc(),c<=32);*s  =c;while(c=gc(),c>32)*s  =c;return s-t;}
    in void ot() {fwrite(sr,1,C 1,stdout);C=-1;}
    in void flush() {if(C>1<<22) ot();}
    template <typename T>
    in void write(T x,char t)
    {
        int y=0;if(x<0)y=1,x=-x;while(z[  Z]=x 48,x/=10);
        if(y)z[  Z]='-';while(sr[  C]=z[Z],--Z);sr[  C]=t;flush();
    }
    in void write(char *s) {int l=strlen(s);for(int i=0;i<l;i  )sr[  C]=*s  ;sr[  C]='n';flush();}
};
using namespace fast_io;
#define pii pair<int,int>
#define fi first
#define se second
const int N=1e5 5;
int n,m,a,b;pii c[N<<1];
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i  ) c[i]={read(),1};
    for(int i=1;i<=m;i  ) c[n i]={read(),0};
    sort(c 1,c n m 1);
    for(int i=1;i<=n m;i  ) c[i].se?b?a  ,b--:0:b  ;
    write(a,'n'); 
    return ot(),0;
}
it

0 人点赞