10.3 Morning
Problem A. problem
【题目描述】
【输入描述】
第一行三个数n, m, k,代表棋盘的行数、列数和小葱的个数。
接下来k行每行三个数x[i], y[i], d[i], f[i],表示每个小葱一开始所在的行、列、面朝的方向以及战斗力。其中d[i]只可能是0,1,2,3中的一个,分别代表上下左右四个方 向。
最后一行一个整数t,代表结束的时刻。
【输出描述】
k行每行两个数,代表每棵小葱在时刻t的时候所在的位置。
【输入输出样例】
【input】
3 3 3
1 1 1 1
2 2 2 2
3 3 3 3
4
【output】
2 1
2 3
3 1
【数据范围】
【代码实现】
20分代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1005
using namespace std;
int mx[4]={-1,1,0,0},my[4]={0,0,-1,1};
int t,n,m,k,num[N][N];
struct qq{
int f,d,x,y,dd;
}a[N];
bool check(int s){
int nx=a[s].x+mx[a[s].d],ny=a[s].y+my[a[s].d];
if(nx==0||ny==0||nx==n+1||ny==m+1)return 1;
return 0;
}
int main(){
freopen("problem.in","r",stdin);
freopen("problem.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++){
scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].d,&a[i].f);
num[a[i].x][a[i].y]=a[i].f;
}
scanf("%d",&t);
while(t--){
for(int i=1;i<=k;i++){//clear
if(a[i].dd)continue;
num[a[i].x][a[i].y]=0;
}
for(int i=1;i<=k;i++){//move
if(a[i].dd)continue;
if(check(i))a[i].d^=1;
else {
a[i].x+=mx[a[i].d],a[i].y+=my[a[i].d];
num[a[i].x][a[i].y]=max(num[a[i].x][a[i].y],a[i].f);
}
}
for(int i=1;i<=k;i++)if(a[i].dd==0&&num[a[i].x][a[i].y]>a[i].f)a[i].dd=1;//fight
}
for(int i=1;i<=k;i++)printf("%d %d\n",a[i].x,a[i].y);
return 0;
}
40分代码
#include <cstdio>
#include <vector>
using namespace std;
int G[202][202][5];
int N,M,K,T;
int d[1001],x[1001],y[1001],f[1001],dead[1001];
int main () {
freopen("problem.in","r",stdin);
freopen("problem.out","w",stdout);
scanf("%d%d%d",&N,&M,&K);
for(int i=1;i<=K;i++) {
scanf("%d%d%d%d",&x[i],&y[i],&d[i],&f[i]);
G[x[i]][y[i]][++G[x[i]][y[i]][0]]=i;
}
scanf("%d",&T);
for(int t=1;t<=T;t++) {
for(int i=1;i<=K;i++) {
if(dead[i])
continue;
if(d[i]==0) {
if(x[i]-1<1) {
d[i]=1;
continue;
}
G[x[i]][y[i]][G[x[i]][y[i]][0]--]=0;
x[i]--;
G[x[i]][y[i]][++G[x[i]][y[i]][0]]=i;
}
if(d[i]==1) {
if(x[i]+1>N) {
d[i]=0;
continue;
}
G[x[i]][y[i]][G[x[i]][y[i]][0]--]=0;
x[i]++;
G[x[i]][y[i]][++G[x[i]][y[i]][0]]=i;
}
if(d[i]==2) {
if(y[i]-1<1) {
d[i]=3;
continue;
}
G[x[i]][y[i]][G[x[i]][y[i]][0]--]=0;
y[i]--;
G[x[i]][y[i]][++G[x[i]][y[i]][0]]=i;
}
if(d[i]==3) {
if(y[i]+1>M) {
d[i]=2;
continue;
}
G[x[i]][y[i]][G[x[i]][y[i]][0]--]=0;
y[i]++;
G[x[i]][y[i]][++G[x[i]][y[i]][0]]=i;
}
}
for(int i=1;i<=N;i++)
for(int j=1;j<=M;j++)
if(G[i][j][0]>1) {
int Max=0,alive=0;
for(int k=1;k<=G[i][j][0];k++)
if(f[G[i][j][k]]>Max)
Max=f[G[i][j][k]],alive=G[i][j][k];
for(int k=1;k<=G[i][j][0];k++)
if(G[i][j][k]!=alive)
dead[G[i][j][k]]=1;
for(int k=1;k<=G[i][j][0];k++)
G[i][j][k]=0;
G[i][j][0]=1;
G[i][j][1]=alive;
}
}
for(int i=1;i<=K;i++)
printf("%d %d\n",x[i],y[i]);
return 0;
}
爆零的std(100分代码)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110;
const int maxk=1010;
int n,m,k,x[maxk],y[maxk],d[maxk],f[maxk],z[maxk],t;
bool alive[maxk];
int dx[4],dy[4];
void move(int p)
{
x[p] += dx[d[p]];
y[p] += dy[d[p]];
if (x[p]<1 || x[p]>n || y[p]<1 || y[p]>m)
{
x[p] -= dx[d[p]];
y[p] -= dy[d[p]];
d[p] ^= 1;
}
}
bool cmp(int a,int b)
{
if (x[a]!=x[b]) return x[a]<x[b];
else return y[a]<y[b];
}
int main()
{
dx[0]=-1;dx[1]=1;dy[2]=-1;dy[3]=1;
scanf("%d%d%d",&n,&m,&k);
for (int a=1;a<=k;a++)
scanf("%d%d%d%d",&x[a],&y[a],&d[a],&f[a]);
for (int a=1;a<=k;a++)
{
alive[a]=true;
z[a]=a;
}
scanf("%d",&t);
for (;t--;)
{
for (int a=1;a<=k;a++)
if (alive[a]) move(a);
sort(z+1,z+k+1,cmp);
for (int a=1;a<=k;)
{
int b=a,p=-1;
while (x[z[b]]==x[z[a]] && y[z[b]]==y[z[a]] && b<=k)
{
if (alive[z[b]] && (p==-1 || f[z[b]]>f[z[p]])) p=b;
b++;
}
for (int c=a;c<b;c++)
if (p!=-1 && c!=p) alive[z[c]]=false;
a=b;
}
}
for (int a=1;a<=k;a++)
printf("%d %d\n",x[a],y[a]);
return 0;
}
Problem B. too
【题目描述】
【输入描述】
第一行两个整数N, M代表数的个数和规则数量。 接下来每行一个字符和一个整数t, n代表一条规则。
【输出描述】
输出一行一个整数,代表答案对12345取模之后的结果。
【输入输出样例】
【input】
5 2
a 1
b 2
【output】
16
方案包括: aaaaa, aaabb, aabab, aabba, abaab, ababa, abbaa, baaab, baaba, babaa, bbaaa, abbbb, babbb, bbabb, bbbab, bbbba。
【数据范围】
【代码实现】
20分代码
#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define R register
#define ll long long
using namespace std;
const int mod = 12345;
int n, m, c[600][600], rule[100];
inline void read(int &x)
{
x = 0;
char ch = getchar();
while(!isdigit(ch))
{
ch = getchar();
}
while(isdigit(ch))
{
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return;
}
void work1()
{
c[0][0] = 1;
for(R int i = 1; i <= n; ++i)
{
c[i][0] = 1;
for(R int j = 1; j <= i; ++j)
{
c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
}
}
for(R int i = 1; i <= m; ++i)
{
char ch;
cin >> ch, read(rule[i]);
}
int ans = 0;
for(R int i = 0; i * rule[1] <= n; ++i)
{
for(R int j = 0; j * rule[2] + i * rule[1] <= n; ++j)
{
if((n - j * rule[2] + i * rule[1]) % rule[3])
{
continue;
}
ans = (ans + c[n][i * rule[1]] * c[n - i * rule[1]][j * rule[2]]) % mod;
}
}
cout << ans;
return;
}
int main()
{
srand(19260817);
freopen("too.in", "r", stdin);
freopen("too.out", "w", stdout);
read(n), read(m);
if(n <= 25)
{
work1();
return 0;
}
cout << (rand() * rand()) % 12345;
return 0;
}
60分代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 200
#define mod 12345
#define LL long long
using namespace std;
int num[N][N],tt,sum,now[N];
int X[N],f[N],ans[N][N],sss[N][N],tmp[N][N];
LL n;int m;
char c[N];int a[N];
int gcd(int x,int y){
if(!y)return x;
return gcd(y,x%y);
}
void mul(int op){
memset(sss,0,sizeof(sss));
if(op==1){
for(int i=1;i<=tt;i++)
for(int j=1;j<=tt;j++)
for(int k=1;k<=tt;k++)
sss[i][j]=(sss[i][j]+ans[i][k]*tmp[k][j])%mod;
for(int i=1;i<=tt;i++)
for(int j=1;j<=tt;j++)ans[i][j]=sss[i][j];
}
else{
for(int i=1;i<=tt;i++)
for(int j=1;j<=tt;j++)
for(int k=1;k<=tt;k++)
sss[i][j]=(sss[i][j]+tmp[i][k]*tmp[k][j])%mod;
for(int i=1;i<=tt;i++)
for(int j=1;j<=tt;j++)tmp[i][j]=sss[i][j];
}
}
void qpow(){
while(n){
if(n&1)mul(1);
mul(2);n>>=1;
}
for(int i=1;i<=tt;i++)
for(int j=1;j<=tt;j++)
f[i]=(f[i]+ans[i][j]*X[j])%mod;
}
bool df(int s1,int s2){
int z=0;
for(int i=0;i<55;i++)
if(num[s1][i]!=num[s2][i])z++;
if(z>=2)return 0;
for(int i=0;i<55;i++)
if(num[s1][i]!=num[s2][i])
if(num[s2][i]-num[s1][i]==1||(num[s1][i]==a[i]-1&&num[s2][i]==0))return 1;
return 0;
}
void prework(){
X[1]=1;
for(int i=1;i<=tt;i++)ans[i][i]=1;
for(int i=1;i<=tt;i++){
for(int j=1;j<=tt;j++){
if(i==j)tmp[i][j]=sum;
if(df(i,j))tmp[i][j]=1;
}
}
}
void dfs(int x){
if(x==55){
tt++;
for(int i=0;i<55;i++)num[tt][i]=now[i];
return;
}
if(a[x]==0)dfs(x+1);
for(int i=0;i<a[x];i++)now[x]=i,dfs(x+1);
}
int main(){
freopen("too.in","r",stdin);
freopen("too.out","w",stdout);
cin>>n>>m;
for(int i=1,x;i<=m;i++){
cin>>c[i]>>x;int ss;
if(c[i]>='a')ss=c[i]-'a'+26;
else ss=c[i]-'A';
if(a[ss])a[ss]=a[ss]*x/gcd(a[ss],x);
else a[ss]=x;
}
for(int i=0;i<55;i++)if(a[i]==1)sum++;
dfs(0); prework(); qpow();
printf("%d",f[1]);
return 0;
}
爆零的std(100分代码)
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#define inc(a,b) {a+=b;if (a>=mo) a-=mo;}
const int mo=12345;
int s,cnt,num,multi[30],c,pos[30];
long long n;
char st[3];
vector<int> status[125],nowway,v[30];
map< vector <int> , int > id;
int m1[125][125],m2[125][125],m3[125][125];
void dfs(int now)
{
if (now==cnt)
{
num++;
status[num]=nowway;
id[nowway]=num;
}
else
{
for (int a=0;a<multi[now];a++)
{
nowway.push_back(a);
dfs(now+1);
nowway.pop_back();
}
}
}
int gcd(int a,int b)
{
if (a % b==0) return b;
else return gcd(b,a % b);
}
int main()
{
cin>>n;
scanf("%d",&c);
for (int a=1;a<=c;a++)
{
scanf("%s",st);
int nowv;
scanf("%d",&nowv);
v[st[0]-'A'+1].push_back(nowv);
}
s=1;
for (int a=1;a<=26;a++)
if (v[a].size())
{
sort(v[a].begin(),v[a].end());
v[a].resize(unique(v[a].begin(),v[a].end())-v[a].begin());
int size=0;
for (int b=0;b<(int)v[a].size();b++)
{
bool able=true;
for (int c=0;c<b;c++)
if (v[a][b]%v[a][c]==0) able=false;
if (able)
{
v[a][size]=v[a][b];
size++;
}
}
v[a].resize(size);
if (v[a].back()==1) continue;
int lcm=1;
for (int b=0;b<(int)v[a].size();b++)
lcm=lcm*v[a][b]/gcd(v[a][b],lcm);
s*=lcm;
multi[cnt]=lcm;
pos[a]=cnt;
cnt++;
}
dfs(0);
for (int a=1;a<=num;a++)
{
nowway=status[a];
for (int b=1;b<=26;b++)
if (v[b].size())
{
if (v[b].back()==1) m1[a][a]++;
else
{
nowway[pos[b]]++;
nowway[pos[b]]%=multi[pos[b]];
int idx=id[nowway];
m1[a][idx]++;
nowway[pos[b]]+=multi[pos[b]]-1;
nowway[pos[b]]%=multi[pos[b]];
}
}
}
m2[1][1]=1;
while (n)
{
if (n&1)
{
memset(m3,0,sizeof(m3));
for (int a=1;a<=s;a++)
for (int b=1;b<=s;b++)
for (int c=1;c<=s;c++)
inc(m3[a][c],m2[a][b]*m1[b][c]%mo);
for (int a=1;a<=s;a++)
for (int b=1;b<=s;b++)
m2[a][b]=m3[a][b];
}
memset(m3,0,sizeof(m3));
for (int a=1;a<=s;a++)
for (int b=1;b<=s;b++)
for (int c=1;c<=s;c++)
inc(m3[a][c],m1[a][b]*m1[b][c]%mo);
for (int a=1;a<=s;a++)
for (int b=1;b<=s;b++)
m1[a][b]=m3[a][b];
n>>=1;
}
int ans=0;
for (int a=1;a<=num;a++)
{
nowway=status[a];
bool able=true;
for (int b=1;b<=26;b++)
if (v[b].size())
{
if (v[b].back()==1) continue;
bool fail=true;
for (int c=0;c<(int)v[b].size();c++)
if (nowway[pos[b]]%v[b][c]==0)
{
fail=false;
break;
}
if (fail)
{
able=false;
break;
}
}
if (able) ans=(ans+m2[1][a])%mo;
}
printf("%d\n",ans);
return 0;
}
Problem C. easy
【题目描述】
【输入格式】
第一行一个整数n,表示点的个数。 接下来一行n个整数,第i个整数表示第i个点的点权Ai。
【输出格式】
第一行输出为了获得点愉悦程度需要的最少花费。
接下来n行,第i行输岀0,1,2中的某一个数,输出0表示不买这一类糖果,输出1表示买小糖果,输出2表示买大糖果。如果有多种最优方案,输出其中一种即可。
【输入输出样例】
一行一个整数表示答案对991127取模的结果。
【input】
3
1 3 2
【output】
1
【数据范围】
【代码实现】
15分代码
#include<iostream>
#include<cstdio>
using namespace std;
const int mod = 991127;
int n,a[100005],ans;
struct edge{
int node,next,data;
}e[200005];
int tot,head[10005];
int num(int x)
{
int res=0;
while(x)
{
if(x&1) res++;
x>>=1;
}
return res;
}
void add(int x,int y,int z)
{
e[++tot].next =head[x];
e[tot].node=y;
e[tot].data =z;
head[x]=tot;
}
void dfs(int u,int ansp)
{
ansp=ansp%mod;
if(u==n)
{
ans+=ansp;
ans=ans%mod;
return;
}
for(int i=head[u];i;i=e[i].next )
{
int tmp=ansp;
ansp*=e[i].data ;
dfs(e[i].node,ansp);
ansp=tmp;
}
}
int main()
{
freopen("easy.in","r",stdin);
freopen("easy.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int t=num(a[i]&a[j]);
if(t>0)
add(i,j,t);
}
dfs(1,1);
printf("%d\n",ans);
return 0;
}
30分代码
#include<iostream>
#include<cstdio>
#define rint register int
#define ull unsigned long long
using namespace std;
const int mod=991127;
const int maxn=1050;
struct edge{
ull to;
ull w;
edge* next;
edge(int to,int w,edge* next) {this->to=to;this->w=w;this->next=next;}
};
edge* head[maxn];
ull f[maxn];
ull val[maxn];
ull counts(int x){
int ans=0;
while(x)
ans+=(x&1),x>>=1;
return ans;
}
int main(){
freopen("easy.in","r",stdin);
freopen("easy.out","w",stdout);
ios::sync_with_stdio(false);
ull n;cin>>n;
for(rint i=1;i<=n;++i)
cin>>val[i];
for(rint i=1;i<=n;++i)
for(rint j=i+1;j<=n;++j){
if(val[i]&val[j]==0)
continue;
head[i]=new edge(j,counts(val[i]&val[j]),head[i]);
}
f[1]=1;
for(rint i=1;i<=n;++i)
for(edge* e=head[i];e;e=e->next)
f[e->to]=(f[e->to] + f[i] * e->w)%mod;
cout<<f[n];
return 0;
}
爆零的std(100分代码)
#include<bits/stdc++.h>
#define MOD 991127
using namespace std;
int n;
const int MAXN=200010;
int a[MAXN],f[30],dp[MAXN];
inline void update(int &a,int b){
a+=b;
if(a>=MOD)a-=MOD;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
memset(f,0,sizeof(f));
for(int i=0;i<30;i++)
if((a[1]>>i)&1) f[i]=1;
dp[1]=1;
for(int i=2;i<=n;i++)
{
for(int j=0;j<30;j++)
if((a[i]>>j)&1)update(dp[i],f[j]);
for(int j=0;j<30;j++)
if((a[i]>>j)&1)update(f[j],dp[i]);
}
printf("%d\n",dp[n]);
return 0;
}