您的位置:首页 > 其它

uoj #73. 【WC2015】未来程序 提交答案题

2018-01-13 11:06 232 查看

题意

本题是一道提交答案题,一共有 10 个测试点。

对于每个测试点,你会得到一段程序的源代码和这段程序的输入。你要运行这个程序,并保存这个程序的输出。

遗憾的是这些程序效率都极其低下,无法在比赛的 55 小时内得到输出。

你需要帮助B君得到这些程序的输出。

题解

program1

就是一个大整数相乘取模

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

LL solve(LL x,LL y,LL mo)
{
LL ans=0;
while (y)
{
if (y&1) (ans+=x)%=mo;
x=x*2%mo;y>>=1;
}
return ans;
}

int main()
{
freopen("program1.in","r",stdin);freopen("program1.out","w",stdout);
for (int i=1;i<=10;i++)
{
LL x,y,z;scanf("%lld%lld%lld",&x,&y,&z);
printf("%lld\n",solve(x,y,z));
}
return 0;
}


program2

矩阵乘法快速幂。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

LL n,MOD;
struct Matrix{LL a[5][5];}a;

void mul(Matrix a,Matrix b,Matrix &c)
{
memset(c.a,0,sizeof(c.a));
for (int i=1;i<=3;i++)
for (int j=1;j<=3;j++)
for (int k=1;k<=3;k++)
(c.a[i][j]+=a.a[i][k]*b.a[k][j])%=MOD;
}

Matrix ksm(Matrix x,LL y)
{
Matrix ans;
memset(ans.a,0,sizeof(ans.a));
for (int i=1;i<=3;i++) ans.a[i][i]=1;
while (y)
{
if (y&1) mul(ans,x,ans);
mul(x,x,x);y>>=1;
}
return ans;
}

int main()
{
freopen("program2.in","r",stdin);freopen("program2.out","w",stdout);
for (int i=1;i<=10;i++)
{
scanf("%lld%lld",&n,&MOD);
a.a[1][1]=a.a[1][2]=a.a[1][3]=a.a[2][2]=a.a[3][1]=1;
a.a[2][1]=2;
a.a[2][3]=a.a[3][2]=a.a[3][3]=0;
a=ksm(a,n);
LL x=a.a[1][1],y=a.a[1][2],z=a.a[1][3];
printf("%lld\n",((x-y*2+z)%MOD+MOD)%MOD);
}
return 0;
}


program3

求k<=4的自然数幂和。前三个记得公式,最后一个懒得推公式就用矩阵乘法来求了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef unsigned long long LL;

LL n;

struct Matrix{LL a[8][8];}a;

void mul(Matrix a,Matrix b,Matrix &c)
{
memset(c.a,0,sizeof(c.a));
for (int i=1;i<=6;i++)
for (int j=1;j<=6;j++)
for (int k=1;k<=6;k++)
c.a[i][j]+=a.a[i][k]*b.a[k][j];
}

Matrix ksm(Matrix x,LL y)
{
Matrix ans;
memset(ans.a,0,sizeof(ans.a));
for (int i=1;i<=6;i++) ans.a[i][i]=1;
while (y)
{
if (y&1) mul(ans,x,ans);
mul(x,x,x);y>>=1;
}
return ans;
}

LL solve(LL n)
{
memset(a.a,0,sizeof(a.a));
a.a[1][1]=a.a[1][2]=a.a[1][3]=a.a[1][4]=a.a[1][5]=a.a[2][2]=a.a[3][3]=a.a[4][4]=a.a[5][5]=a.a[6][6]=a.a[5][6]=1;
a.a[2][3]=2;a.a[2][4]=a.a[3][4]=3;a.a[2][5]=a.a[4][5]=4;a.a[3][5]=6;
a=ksm(a,n);
LL ans=0;
for (int i=1;i<=5;i++) ans+=a.a[i][6];
return ans;
}

int main()
{
freopen("program3.in","r",stdin);freopen("program3.out","w",stdout);
scanf("%llu",&n);
printf("%llu\n",n+1);
printf("%llu\n",n+1);
LL w;
if (n&1) w=(n+1)/2*n;
else w=n/2*(n+1);
printf("%llu\n",w);
printf("%llu\n",w);
LL v1=n,v2=n+1,v3=n*2+1;
if (v1%2==0) v1/=2;
else if (v2%2==0) v2/=2;
else v3/=2;
if (v1%3==0) v1/=3;
else if (v2%3==0) v2/=3;
else v3/=3;
printf("%llu\n",v1*v2*v3);
printf("%llu\n",v1*v2*v3);
printf("%llu\n",w*w);
printf("%llu\n",w*w);
printf("%llu\n",solve(n));
printf("%llu\n",solve(n));
return 0;
}


program4

求矩形内所有黑点到最近白点的距离和。bfs一下就好了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

const int N = 5000, inf = 0x3F3F3F3F;
int n, m, type;
bool data[N + 11][N + 11];

int seed;
int next_rand(){
static const int P = 1000000007, Q = 83978833, R = 8523467;
return seed = ((long long)Q * seed % P * seed + R) % P;
}

void generate_input(){
cin >> n >> m >> type;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
data[i][j] = bool((next_rand() % 8) > 0);
}

long long count1(){
long long ans = 0LL;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(data[i][j]) ans++;
return ans*(ans-1);
}

int abs_int(int x){
return x < 0 ? -x : x;
}

int dist

,dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
queue<pair<int,int> > que;

long long count2(){
long long ans = 0LL;
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (data[i][j]) dist[i][j]=inf;
else dist[i][j]=0,que.push(make_pair(i,j));
while (!que.empty())
{
int x=que.front().first,y=que.front().second;que.pop();
for (int i=0;i<4;i++)
{
int p=x+dx[i],q=y+dy[i];
if (p<0||p>=n||q<0||q>=m||dist[p][q]<inf) continue;
dist[p][q]=dist[x][y]+1;que.push(make_pair(p,q));
}
}
for (int i=0;i<n;i++)
for (int j=0;j<m;j++)
if (data[i][j]) ans+=dist[i][j];
return ans;
}

int main(){
freopen("program4.in","r",stdin);freopen("program4.out","w",stdout);
cin >> seed;
for(int i = 0; i < 10; i++){
generate_input();
cout << (type == 1 ? count2() : count1()) << std::endl;
}
return 0;
}


program5

求n*m的01矩形内,有多少个全1子矩形。拿单调栈随便维护一下就好了。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

const int N = 5011;
int n, m;
bool data

;

int seed;
int next_rand(){
static const int P = 1000000007, Q = 83978833, R = 8523467;
return seed = ((long long)Q * seed % P * seed + R) % P;
}

void generate_input(){
std::cin >> n >> m;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
data[i][j] = bool((next_rand() % 8) > 0);
}

LL s

;
int stack
;

LL count3(){
for (int i=0;i<n;i++)
{
s[i][0]=data[i][0];
for (int j=1;j<m;j++)
if (data[i][j]) s[i][j]=s[i][j-1]+1;
else s[i][j]=0;
}
LL ans=0;
for (int j=0;j<m;j++)
{
int top=0;LL w=0;stack[0]=-1;
for (int i=0;i<n;i++)
{
while (top&&s[stack[top]][j]>=s[i][j])
{
int x=stack[top];
w-=(LL)(x-stack[top-1])*s[x][j];
top--;
}
w+=(LL)(i-stack[top])*s[i][j];
stack[++top]=i;
ans+=w;
}
}
return ans;
}

int main(){
freopen("program5.in","r",stdin);
freopen("program5.out","w",stdout);
cin >> seed;
for(int i = 0; i < 10; i++){
generate_input();
cout << count3() << std::endl;
}
return 0;
}


至于后面的点嘛。。。感觉玩不动了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: