2020年广东工业大学第十届文远知行杯新生程序设计竞赛(同步赛)

第一次水题解,尽管还有三不会
链接

A肥猪的钢琴床

做的时候没想到dp,直接模拟
转化后的字符串可化为 000111000三段,每一段的长度都可能为0
dp数组记录第i个处于第1/2/3段需要删除的最小字符(第个字符可能要被删除)正解是dp

if(s[i]=='1') {
     
            dp[i][0]=dp[i-1][0]+1;
            dp[i][1]=min(dp[i-1][0],dp[i-1][1]);
            dp[i][2]=min(dp[i-1][1],dp[i-1][2])+1;
        }
        else {
     
            dp[i][0]=dp[i-1][0];
            dp[i][1]=min(dp[i-1][0],dp[i-1][1])+1;
            dp[i][2]=min(dp[i-1][1],dp[i-1][2]);

看大佬代码还发现一种神奇的解法
先记录总共的1的数量,然后

     int x=0;
    for(int i=0;i<n;i++){
     
        if(num[i] == 0) x--;
        else x++;
        if(x<0) x =0;
        maxx = max(x,maxx);
    }
    cout<<sum-maxx;

比如有一串01010011001
1有5个,更新maxx为2,这里是最大连续的1
又比如有01011111011111111000
这边遇0的x–意义就成了把中间的0去掉

B签到 水

C母牛的俄罗斯轮盘赌

一开始以为是博弈论,后来发现枚举到十就可以找到规律
1 pig
2 cow
3 pig
4 pig
5 cow
6 pig
7 cow
8 pig
9 pig
10 cow

typedef long long ll;
int main()
{
     
	int t;
	cin>>t;
	while(t--){
     
		int n;
		cin>>n;
		n%=5;
		int flag=0;
		if(n==0||n==2)flag=1;
		if(flag==1)printf("Cow\n");
		else printf("Pig\n");
	}
	return 0;
 } 

D 中学数学题

求q进制下的后导零,而且q是质数,所以有后导零只有可能是阶乘中有q,有几个q就有几个后导零。
这个题的加强版是q不是质数,这个时候就要去打q的因数了
链接

ll N, B;
ll calc(ll n, ll p)
{
     
    ll res = 0;
    while(n){
     
        res += n/p;
        n/=p;
    }
    return res;
}
int main()
{
     
	int T;
	cin>>T;
	while(T--){
     
	    ll sum = 1ll;
    	scanf("%lld %lld", &N, &B);
	    //get_p(B);
		//ll ans = (1ll<<62);
        ll ans = calc(N, B);
		printf("%lld\n", ans);
	}
    return 0;
}

E 枚举求和

看代码,发现规律是(n/k)*(m/k)就好了

int main()
{
     
	int T;
	cin>>T;
	while(T--){
     
		ll n,m,k;
	    scanf("%lld%lld%lld",&n,&m,&k);
	    printf("%lld\n",(n/k)*(m/k));
	}
    return 0;
}

G 排忧解伤

看我的注释

const int N=1e5+5;
ll n,m,s=1,ans=0,a[N];
int main()
{
     
    cin>>n>>m;
    for(int i=1;i<=m;i++) cin>>a[i];
    sort(a+1,a+1+m);//先用桶装爱好,装完了排序
    for(int i=1;i<=n;i++){
     //按座位遍历就好了
        if(a[s]<=i){
     
            ans+=i-a[s];
            s++;
        }
        if(s==m+1) break;
    }
    if(s!=m+1) cout<<-1<<endl;
    else cout<<ans<<endl;
    return 0;
}

I 大大大大签到

K 很基础的模拟题

我一看,啪的一下很快啊,这不就是vector吗,stl大法好

#include
#include
using namespace std;
int n,q;
vector <int > v;
int main()
{
     

	cin>>n>>q;
	
	for(int i=0;i<n;i++){
     
		int tmp;
		scanf("%d",&tmp);
		v.push_back(tmp);
	}
	while(q--){
     
		int op;
		scanf("%d",&op);
		if(op==1){
     
			int pos;
			scanf("%d",&pos);
			v.erase(v.begin()+pos-1);
			n--;
			for(int i=0;i<n;i++){
     
				cout<<v[i]<<' ';
			}
			cout<<endl;
		}
		else if(op==2){
     
			int pos,num;
			scanf("%d%d",&pos,&num);
			v.insert(v.begin()+pos-1,num);n++;
			for(int i=0;i<n;i++){
     
				cout<<v[i]<<' ';
			}
			cout<<endl;
		}
		else{
     
			int pos;
			scanf("%d",&pos);	int tx=v[pos-1];
			for(int i=pos;i<n;i++){
     
			
				if(v[i]==tx){
     
					v.erase(v.begin()+i);
					v[pos-1]+=tx;
					n--;i--;
				}
				else{
     
					break;
				}
			}
			for(int i=0;i<n;i++){
     
				cout<<v[i]<<' ';
			}
			cout<<endl;
		}
	}
    return 0;
}

H 母牛上柱

就正常把圆柱侧面展开,求一下距离就行了,注意夹角可能超过180.

int main() {
     
	int T;
	cin>>T;
	while(T--){
     
		double a,b,c,d;
		cin>>a>>b>>c>>d;
		double x;
		if(fabs(a-b)>180){
     
			x=360-fabs(a-b);
		}
		else x=fabs(a-b);
		x=x*PI/180;
		double t=x*c;
		//cout<
		double res=t*t+d*d;

		printf("%.2f\n",res);
	}
	return 0;
}

F 合并石子

你可能感兴趣的:(笔记)