您的位置:首页 > 其它

NOIP模拟题 [模拟][递推][平衡规划]

2016-11-16 20:17 441 查看
在写暴力的时候也不要放过发现的每一个题目特点,这可能就是正解的关键。

T1:

题意:

求给定一个序列最大公约数为1的最长长度;

分析:

傻逼题,害我读了几次题。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(int i=n;i<m;i++)
#define eachrev(i,n,m) for(int i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "seq"
//for(int i=1;i<=n;i++)
//(double) (ll) LL (int)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const int modd=1e9+7;
ll n,s;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll gcd(ll a,ll b)
{
return (b==0?a:gcd(b,a%b));
}
void init()
{
n=read();
s=read();
for(int i=2;i<=n;i++)
s=gcd(s,read());
}
void work()
{
if(s!=1)printf("-1");
else printf(lld,n);
}
void debug()
{
//
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
//debug();
return 0;
}


T2:

题意:

给定矩阵大小n*m,要求每个n*n矩阵都有k小矩形被涂色的方案总数。

分析:

画一画就会发现,前n列确定以后就确定了方案,接下来乘就行了。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(ll i=n;i<m;i++)
#define eachrev(i,n,m) for(ll i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "table"
//for(ll i=1;i<=n;i++)
//(double) (ll) LL (ll)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const ll Maxn=105;
const ll modd=1e9+7;
ll n,m,k,f[Maxn][Maxn*Maxn],lim2;
ll ans,c[Maxn],ni[Maxn];
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll jc(ll n)
{
ll ret=1;
for(ll i=1;i<=n;i++)
(ret*=i)%=modd;
return ret;
}
ll qm(ll a,ll b)
{
ll ret=1;
while(b){
if(b&1)(ret*=a)%=modd;
(a*=a)%=modd;
b>>=1;
}
return ret;
}
void init()
{
n=read();
m=read();
k=read();
ll lim=jc(n);
lim2=min(n,k);
for(ll i=0;i<=lim2;i++)
c[i]=lim*qm(jc(i),modd-2)%modd*qm(jc(n-i),modd-2)%modd;
}
void work()
{
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=k;j++)
ni[j]=qm(c[j],(m-(ll)i)/n+1LL);
for(int j=0;j<=k;j++)
for(int z=0;z<=j;z++)
(f[j][i]+=f[z][i-1]*ni[j-z]%modd)%=modd;
}
printf(lld,f[k]
);
}
void debug()
{
//
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
//debug();
return 0;
}


T3:

题意:

给定n个点,求组成边与坐标轴平行的正方形的方案数。

分析:

有两个暴力方法,极端情况出现的条件不一样。

所以分一下类就可以了,据说叫平衡规划,高级。

hash才能不T,明天写吧orz。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(int i=n;i<m;i++)
#define eachrev(i,n,m) for(int i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "square"
//for(int i=1;i<=n;i++)
//(double) (ll) LL (int)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const int Maxn=100000+5;
const int modd=1e9+7;
int n,x[Maxn],y[Maxn],tot[Maxn],lll[Maxn];
ll ans;
vector<int>e1[Maxn],e2[Maxn];
un
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
void init()
{
n=read();
for(int i=1;i<=n;i++){
x[i]=read();y[i]=read();
e1[x[i]].push_back(y[i]);
e2[y[i]].push_back(x[i]);
}
for(int i=0;i<=100000;i++)sort(e1[i].begin(),e1[i].end());
for(int i=0;i<=100000;i++)sort(e2[i].begin(),e2[i].end());
}
void work()
{
int mmm=int(sqrt(n))+1;
for(int i=0;i<=100000;i++)
if(e1[i].size()&&e1[i].size()<mmm){
vector<int>::iterator iii=e1[i].begin();
vector<int>::iterator len1=e1[i].end();
vector<int>::iterator x1;
for(;iii+1<len1;iii++)
for(x1=iii+1;x1<len1;x1++)
{
vector<int>::iterator tmp=lower_bound(e2[(*x1)].begin(),e2[(*x1)].end(),i+(*x1)-(*iii));
vector<int>::iterator tmp2=lower_bound(e2[(*iii)].begin(),e2[(*iii)].end(),i+(*x1)-(*iii));
if((*tmp)==i+(*x1)-(*iii)&&(*tmp2)==i+(*x1)-(*iii))
ans+=1LL;
if(i-(*x1)+(*iii)>=0&&lll[i-(*x1)+(*iii)]){
vector<int>::iterator tmp=lower_bound(e2[(*x1)].begin(),e2[(*x1)].end(),i-(*x1)+(*iii));
vector<int>::iterator tmp2=lower_bound(e2[(*iii)].begin(),e2[(*iii)].end(),i-(*x1)+(*iii));
if((*tmp)==i-(*x1)+(*iii)&&(*tmp2)==i-(*x1)+(*iii))
ans+=1LL;
}
}
}
else if(e1[i].size()){tot[++tot[0]]=i;lll[i]=1;}
for(int z=1;z<tot[0];z++)
for(int kk=z+1;kk<=tot[0];kk++){
int i=tot[z];
int j=tot[kk];
vector<int>::iterator iii=e1[i].begin();
vector<int>::iterator len1=e1[i].end();
for(;iii<len1;iii++){
vector<int>::iterator tmp=lower_bound(e1[i].begin(),e1[i].end(),(*iii)+i-j);
vector<int>::iterator tmp2=lower_bound(e1[j].begin(),e1[j].end(),(*iii));
if((*tmp)==(*iii)+i-j&&(*tmp2)==(*iii))
ans+=1LL;
}
}
printf(lld,ans);
}
void debug()
{
//
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
//debug();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息