1. 程式人生 > >【蒻爆了的NOIP系列--普及組複賽】(3)NOIP2012普及組複賽題解

【蒻爆了的NOIP系列--普及組複賽】(3)NOIP2012普及組複賽題解

這只是一個作業,如果有幫到您的,我只能說。。。這不科學。。。
————————————華麗的分割線————————————
第一題:
第一題題目-第1頁
第一個想法:用最基礎的找質數思路解
資料範圍太大,int級,怎麼辦。。。。
正解與暴力只差幾個字元。。。搜尋只搜到sqrt就行了。。。
貼程式碼~~~

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <ctime>
#include <algorithm> #include <queue> #include <map> #define ci const int #define ri register int #define ll long long #define reg register #define boom return #define cmax(a,b) (a)>(b)?(a):(b) #define cmin(a,b) (a)<(b)?(a):(b) #define For(i,a,b) for(i=a;i<b;i++) using namespace
std; int a; int main() { int i; scanf("%d",&a); for(i=sqrt(a);;i--) if(!(a%i)){printf("%d",a/i);return 0;} } //沒有什麼是兩個巴掌不能解決的,如果有就再來兩個巴掌

————————————華麗的分割線————————————
第二題:
第二題題目-第1頁
第二題題目-第2頁
先吐槽一下:這題目真心長啊。。。
不過還是按照以往的慣例:暴力
首先從第一層開始,按照規則模擬累加,一直到頂層,輸出;
可是這有n層,每層要迴圈x次,O(nx)絕對絕對過不了。
怎麼辦?這時就要用上我們暴力的好幫手:縮小範圍了
我們可以在輸入時先算出每層有樓梯的房間的個數。
然後把每個x膜(模)這個數。
然後就O(nm)了
(這題本來想用線上演算法的可這噁心的輸入把最重要的資訊放最後。。。)
下面程式碼醬:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
#define ci const int
#define ri register int
#define ll long long
#define reg register
#define boom return 
#define cmax(a,b) (a)>(b)?(a):(b)
#define cmin(a,b) (a)<(b)?(a):(b)
#define For(i,a,b) for(i=a;i<b;i++)
using namespace std;

int n,m,nowm,ans,poi[10086][110],add[10086];
bool sta[10086][110];
int main()
{
    int i,j,k;

    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        for(j=0;j<m;j++)
        {
            scanf("%d%d",&sta[i][j],&poi[i][j]);
            add[i]+=sta[i][j];
        }
    scanf("%d",&nowm);
    for(i=1;i<=n;i++)
    {
        ans=(ans+poi[i][nowm])%20123;
        k=poi[i][nowm],k=(k-1)%add[i]+1;
        while(k)if(k-=sta[i][nowm])nowm=(nowm+1)%m;
    }
    printf("%d\n",ans);
    return 0; 
}
//沒有什麼是兩個巴掌不能解決的,如果有就再來兩個巴掌

對了還有一件事就是這題坑很多
下面是坑的總結(由lwc學神總結):
第2題的坑
————————————華麗的分割線————————————
第三題:
第三題題目-第1頁
一道dp
狀態:f[i][j]表示就擺前i種花共j盆的方案數
狀態轉移方橙:
f[i][j]=(f[i][j]+f[i-1][j-k])%1000007|k=0~min(a[i]>j)
程式碼:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
#define ci const int
#define ri register int
#define ll long long
#define reg register
#define boom return 
#define cmax(a,b) (a)>(b)?(a):(b)
#define cmin(a,b) (a)<(b)?(a):(b)
#define For(i,a,b) for(i=a;i<b;i++)
using namespace std;

ci MAXN=110;
int n,m,a[MAXN],f[MAXN][MAXN]; 
int main()
{
    int i,j,k,l;

    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    f[0][0]=1;
 //   cout<<n<<" "<<m<<endl;
    for(i=1;i<=n;i++)  
        for(j=0;j<=m;j++)  
        {  
            l=a[i]>j?j:a[i];  
            for (k=0;k<=l;++k)f[i][j]=(f[i][j]+f[i-1][j-k])%1000007;
//          cout<<n<<" "<<m<<endl;  
        }  
    printf("%d",f[n][m]);
    return 0;    
}  
//沒有什麼是兩個巴掌不能解決的,如果有就再來兩個巴掌

————————————華麗的分割線————————————
第四題:
第四題題目-第1頁
第四題題目-第2頁
文化之旅。。。
做完這道題我沒文化了。
這道題AC的方法有很多(話說我為啥不寫正解有很多呢)
比如說我就是Floyd判是否排斥的。。。
不過這道題有個很噁心的地方。。。
就是這道題沒有正解。。。(明白了把qwq)
當年zzq神犇出了個數據把眾演算法都卡掉了。。。
不過CCF資料水AC還是沒問題。。。
程式碼:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <ctime>
#include <algorithm>
#include <queue>
#include <map>
#define ci const int
#define ri register int
#define ll long long
#define reg register
#define boom return 
#define cmax(a,b) (a)>(b)?(a):(b)
#define cmin(a,b) (a)<(b)?(a):(b)
#define For(i,a,b) for(i=a;i<b;i++)
using namespace std;

ci MAXN=110,inf=2333333;
int n,k,m,s,t,a[MAXN][MAXN],b[MAXN],c[MAXN][MAXN];
int main()
{
    int i,j,l,x,y,z;

    scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
    for(i=1;i<=n;i++)for(j=1;j<=n;j++)c[i][j]=inf;
    for(i=1;i<=n;i++)scanf("%d",&b[i]);
    for(i=1;i<=k;i++)for(j=1;j<=k;j++)scanf("%d",&a[i][j]);
    for(i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),c[x][y]=c[y][x]=z;
    for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(a[b[i]][b[j]])c[i][j]=inf;
    for(l=1;l<=n;l++)for(i=1;i<=n;i++)for(j=1;j<=n;j++)
        c[i][j]=min(c[i][j],c[i][l]+c[l][j]);
    printf("%d",(c[t][s]==inf)?-1:c[t][s]);
    return 0;    
}  
//沒有什麼是兩個巴掌不能解決的,如果有就再來兩個巴掌

看到洛谷上有人寫A*。、。
也錯了。,。
————————————華麗的分割線————————————
今天洛谷大吉好開森~~~