考察知识:枚举,二维数组
算法难度:X+ 实现难度:XX
分析:
权值储存用二维数组实现,直接枚举放正方形的坐标(x,y)并计算覆盖权值即可
注意下标不要越界。
代码:
#include
#include
using namespace std;
int d,n,g[130][130];
void ready(){//输入数据
int x,y,k;
scanf("%d%d",&d,&n);
for(int i=1;i<=n;i++) scanf("%d%d%d",&x,&y,&k),g[x][y]=k;
}
void solve(){
int cnt,maxv=0;
for(int i=0;i<=128;i++)
for(int j=0;j<=128;j++){//枚举正方形
int L=max(0,i-d),U=max(0,j-d),
R=min(128,i+d),D=min(128,j+d),
t=0;//注意不要越界
for(int i_=L;i_<=R;i_++)
for(int j_=U;j_<=D;j_++)
t+=g[i_][j_];
if(t>maxv) maxv=t,cnt=1;
else if(t==maxv) cnt++;
}
printf("%d %d\n",cnt,maxv);
}
int main(){
ready();
solve();
return 0;
}
考察知识:图论,图的最短路
算法难度:XXX 实现难度:XXX
分析:
我们先寻找满足条件的所有节点,然后求起点到终点的最短路就可以了。
怎么寻找满足条件的最短路呢:我们先反向见一个图,从终点开始dfs/bfs,标记可以到达的所有节点,然后枚举每一个被标记节点,枚举这个节点所有可以到达的边是否被标记,从而判断这个节点是否满足条件。
代码:
#include
#include
#include
#include
using namespace std;
const int maxn=10005,maxm=200005;
struct edge{
int to,next;
}e[maxm],e_[maxm];
int head[maxn],head_[maxn],np,np_,n,m,s,t;
void adde(int u,int v){
e[++np]=(edge){v,head[u]};
head[u]=np;
}
void adde_(int u,int v){//反向建图
e_[++np_]=(edge){v,head_[u]};
head_[u]=np_;
}
int d[maxn];
bool node[maxn],vis[maxn];
void dfs(int i){
vis[i]=true;
for(int p=head_[i];p;p=e_[p].next){
int j=e_[p].to;
if(!vis[j]) dfs(j);
}
}
void build(){
int u,v;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
if(u!=v) adde(u,v),adde_(v,u);
}
scanf("%d%d",&s,&t);
dfs(t);
for(int i=1;i<=n;i++) if(vis[i]){//寻找满足条件节点
node[i]=true;
for(int p=head[i];p;p=e[p].next){
int j=e[p].to;
if(!vis[j]){node[i]=false;break;}
}
}
}
void bfs(){
queueq;
memset(vis,0,sizeof(vis));
if(node[s]) q.push(s);
vis[s]=true;
while(!q.empty()){
int i=q.front();q.pop();
for(int p=head[i];p;p=e[p].next){
int j=e[p].to;
if(!vis[j]&&node[j]) vis[j]=true,d[j]=d[i]+1,q.push(j);
}
}
printf("%d\n",d[t]==0?-1:d[t]);
}
int main(){
build();
bfs();
return 0;
}
考察知识:数论,枚举
算法难度:XXX+ 实现难度:XXX+
分析:
高次方程求根并不简单,我们定义:,所以我们考虑枚举[1,m]的所有整数,并判断f(x)是否等于0。
可以看到ai非常大,所以我们考虑求 f(x) mod MD,为了防止答案错误,其中MD应该取很大,而且我们应该至少取两个模数。
对于f(x)的计算,我们用秦九韶算法,总时间复杂度O(nm)。由于多次取模还是可能有巧合,但大多数情况下我们的分数可以达到90+。
代码:
#include
#include
#include
#include
using namespace std;
const int MD=10000007,MD_=100000003;
int n,m,a[105],a_[105],cnt,ansq[105];
void get_n(int& x,int& y){
bool flag=false;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=true;
ch=getchar();
}
while(isdigit(ch))
x=(x*10+ch-'0')%MD,
y=(y*10+ch-'0')%MD_,
ch=getchar();
if(flag) x=-x,y=-y;
}
void solve(){
for(int x=1;x<=m;x++) if(cnt