2019年广东工业大学腾讯杯新生程序设计竞赛(同步赛)(E(dp),G(组合数学),H(打表),I(欧拉降幂),J(推方程or找规律),K(解方程),M(水题)))

这场打的很迷。。。卡K了,导致后面很多简单的没写

研究了很久发现只有(x+1)  和   x  的立方差才是质数

实时过更新

题目链接

A,B,C,D签到题就不写了。

E-缺席的神官

思路正确,转移莫名写了个三层for循环的,然后一直不知道怎么优化。。其实两层for循环已经想出来了,莫名奇妙的自己否定了自己。。

三层for比较好理解:

状态方程:设dp[i][j]为前i天分割j个时间段的最小工作时间。。

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=2e3+10;
const ll inf=0x3f3f3f3f3f3f3f3f;
int n,m,k;
ll dp[N][N],a[N];
int main()
{
	cin>>n>>m>>k;
	for(int i=1;i<=n;++i)
        scanf("%lld",&a[i]);

	memset(dp,inf,sizeof(dp));

    for(int i=1;i<=k;++i)
    for(int j=1;j<=i;++j)
        dp[i][j]=1;

	for(int i=1;i<=n;++i)
        dp[1][i]=a[i]-a[1]+1;


	for(int i=2;i<=k;++i){
        for(int j=1;j<=n;++j){
            for(int t=j;t<=n;++t){
                dp[i][t]=min(dp[i][t],dp[i-1][j-1]+a[t]-a[j]+1);
            }
        }
	}

	printf("%lld\n",dp[k][n]);

}

正解:

#include
using namespace std;
#define ll long long
const int w=2e5+5;
int n,m,k;
int a[w];
int dp[2005][2005];
int main()
{
    int i,j;
    scanf("%d %d %d",&n,&m,&k);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(dp,0x3f3f3f3f,sizeof(dp));
    dp[0][0]=0;
    for(i=1;i<=n;i++)
        for(j=1;j<=min(i,k);j++)
        {
            dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);
            dp[i][j]=min(dp[i][j],dp[i-1][j]+a[i]-a[i-1]);
        }
    printf("%d\n",dp[n][k]);
    return 0;
}

G-虚数的纸牌

看官方题解:

2019年广东工业大学腾讯杯新生程序设计竞赛(同步赛)(E(dp),G(组合数学),H(打表),I(欧拉降幂),J(推方程or找规律),K(解方程),M(水题)))_第1张图片

#include
#include
#include
#include
int main()
{
   int a[15];
   char str[20];
   int t,i,j,sum;
   scanf("%d",&t);
   getchar();
   while(t--){
    sum=17;
    scanf("%s",str);
    memset(a,0,sizeof(a));
    for(i=0;i<17;i++){
        if(str[i]>='3'&&str[i]<='9'){
            a[str[i]-'3']++;
           }else{
            if(str[i]=='0'){
                a[7]++;
               }else if(str[i]=='J'){
                a[8]++;
               }else if(str[i]=='Q'){
                a[9]++;
               }else if(str[i]=='K'){
                a[10]++;
               }else if(str[i]=='A'){
                a[11]++;
               }else if(str[i]=='2'){
                a[12]++;
               }
           }
       }
       
       for(i=0;i<=12;i++){
           if(a[i]==4){
            sum++;//一炸 
            }
       }
  
       for(i=0;i<=12;i++){
        if(a[i]==2){
            sum++;//一对 
           }else if(a[i]==3){
            sum+=3;//一对 
           }else if(a[i]==4){
            sum+=6;//一对 
           }
       }
       
       for(i=0;i<=12;i++){
        if(a[i]==4){
            sum+=4*13;//三带一 
           }else if(a[i]==3){
            sum+=14;//三带一
           }
       }
       
       for(i=0;i<=12;i++){
         for(j=0;j<=12;j++){
            if(i!=j){
                if(a[i]==3&&a[j]==2){
                    sum++;//三带2 
                    }else if(a[i]==3&&a[j]==3){
                        sum+=3;// 三带2
                    }else if(a[i]==3&&a[j]==4){
                        sum+=6;//三带2 
                    }else if(a[i]==4&&a[j]==2){
                        sum+=4;//三带2  
                    }else if(a[i]==4&&a[j]==3){
                        sum+=12;//三带2  
                    }else if(a[i]==4&&a[j]==4){
                        sum+=24;//三带2  
                    }
                }
            }
       }
       
       int s=1;
       for(i=0;i<=8;i++){
        s=1;
         for(j=i;j

H-绵羊的银币

打个表就发现规律了。1 1 2 2 2 2 4 4 4 4 4 4 4 4 

简单题

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e4+10;
const ll M=1e18;
ll f[N],num[N];

int main()
{
    f[0]=1;
	f[1]=1;
	num[1]=2;

	for(int i=2;i<=63;++i){
        f[i]=f[i-1]+f[i-2];
        num[i]=num[i-1]*2;
        //printf("i:%d num:%lld\n",i,num[i]);
	}
	int _;cin>>_;while(_--)
	{
	    ll n;
	    scanf("%lld",&n);
	    if(n==0){
            puts("0");
            continue;
	    }
	    for(int i=1;i<=62;++i){
            if(num[i-1]<=n&&n

 

I-迷途的怪物

欧拉降幂的裸题了

#include
using namespace std;
typedef long long ll;
const int N=1e6+10;
ll p;
char s[N];
ll powmod(ll a,ll b,ll mod)
{
    ll res=1;
    for(;b;b>>=1){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
    }
    return res;
}
int main()
{
    int _;cin>>_;while(_--)
    {
        scanf("%lld%s",&p,s+1);
        int len=strlen(s+1);
        ll n=0;
        for(int i=1;i<=len;++i){
            n=(n*10+s[i]-'0')%(p-1);
        }
        printf("%lld\n",powmod(p-1,n,p));
    }
}

J-简单的数学

看官方题解:

2019年广东工业大学腾讯杯新生程序设计竞赛(同步赛)(E(dp),G(组合数学),H(打表),I(欧拉降幂),J(推方程or找规律),K(解方程),M(水题)))_第2张图片

我手推n=3都难。。。

只能解法2  得到递推式,再来推前几项找规律

#include
using namespace std;
typedef long long ll;
const int maxn=2e5+50;
void solve(){
    ll n;scanf("%lld",&n);
    if(n%2==0) printf("-%lld\n",n*(n+1));
    else printf("%lld\n",n*(n+1));
}
int main(){
    int t;scanf("%d",&t);while(t--){
        solve();
    }
}

K-消亡的质数

解方程:

知道了性质:只有(x+1)  和   x  的立方差  研究很久研究出来的

那么方程:(x+1)*(x+1)*(x+1)-x*x*x=p;

x的3次方一减就没了,剩下的是一元二次方程。。。判断一元二次方程是否有解即可。。。

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e15;

int main()
{

	int _;cin>>_;while(_--)
	{
	    ll p;
	    scanf("%lld",&p);
	    ll a=3,b=-3,c=1-p;
	    ll t=b*b-4*a*c;
	    ll sq=sqrt((double)t);
	    if(sq*sq!=t) puts("NO");
	    else{
            ll fz=3+sq;
            if(fz%6!=0) puts("NO");
            else puts("YES");
	    }
	}
}

M-破碎的愿望

水题。。

最终的字符串形式   就是从1到最后,再从最后到1,那么将k取下模即可。。

#include
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
char s[100];
int main()
{
	ll n,k;
	scanf("%lld%lld",&n,&k);
	scanf("%s",s+1);
	ll t=k/n;
	if(k%n!=0) ++t;
	k=k-n*(t-1);
	if(t%2){
        printf("%c",s[k]);
	}
	else{
        printf("%c",s[n-k+1]);
	}
}
/*
5 5
12345
ans:5

5 6
12345
ans:
5

5 10
12345
ans:1

5 11
12345
ans:1
*/

 

你可能感兴趣的:(牛客题解)