NOIP2014Day2

T1 无线网络发射器选址

大模拟
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
using namespace std;
#define ll long long
inline 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*10+ch-'0';ch=getchar();}
    return x*f;
}
int d,n,sum[130][130],ans1,ans2;
int main()
{
    d=read();n=read();
    for(int i=1;i<=n;i++)
    {
        int x=read(),y=read(),num=read();
        for(int j=max(x-d,0);j<=min(128,x+d);j++)
            for(int k=max(y-d,0);k<=min(128,y+d);k++) sum[j][k]+=num;
    }
    for(int i=0;i<=128;i++)
        for(int j=0;j<=128;j++) 
        {	
            if(sum[i][j]>ans2){ans2=sum[i][j];ans1=0;}
            if(sum[i][j]==ans2) ans1++;
        }
    cout<<ans1<<' '<<ans2<<"\n";
}

T2 寻找道路

建反边,跑出所有能到达t的点。
预处理出所有的符合条件的点
然后就是裸的最短路了。
/**************************************************************
    User: ZincSabian
    Language: C++
****************************************************************/
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
inline ll _() {
	ll x=0,f=1; char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())
		if(ch=='-')f=-f;
	for(;ch>='0'&&ch<='9';ch=getchar())
		x=x*10+ch-'0';
	return x*f;
}
#define _ _()
const int N=200005;
struct Edge{ int to,nxt; }e[N<<1],E[N<<1];
int cnt,Cnt,head[N],Head[N];
inline void insert(int u,int v) { e[cnt]=(Edge) { v,head[u] }; head[u]=cnt++; E[Cnt]=(Edge) { u,Head[v] }; Head[v]=Cnt++;}
int n,m,s,t,chk[N],vis[N],vis2[N],dis[N];
inline void bfs1() {
	queue<int> q;
	q.push(t);
	while(!q.empty()) {
		int now=q.front(); q.pop();
		vis[now]=1;
		for(int i=Head[now];~i;i=E[i].nxt)
			if(!vis[E[i].to]) q.push(E[i].to);
	}
}
struct node { int pos,dis; };
bool operator <(node a,node b) { return a.dis>b.dis; }
inline void bfs2() {
	priority_queue<node> q;
	for(int i=1;i<=n;i++) dis[i]=2e9;
	q.push((node){s,0});
	dis[s]=0;
	while(!q.empty()) {
		int now=(q.top()).pos,Dis=(q.top()).dis; q.pop();
		if(vis2[now]) continue;
		vis2[now]=1;
		for(int i=head[now];~i;i=e[i].nxt)
			if(dis[e[i].to]>Dis+1&&chk[e[i].to]){
				dis[e[i].to]=Dis+1;
				q.push((node){e[i].to,dis[e[i].to]});
			}
	}
}
int main() {
	memset(head,-1,sizeof(head));
	memset(Head,-1,sizeof(Head));
	n=_; m=_;
	for(int i=1,u,v;i<=m;i++) {
		u=_; v=_;
		if(u!=v) insert(u,v);
	}
	s=_; t=_;
	bfs1();
	for(int i=1;i<=n;i++) {
		chk[i]=vis[i];
		for(int j=head[i];~j;j=e[j].nxt)
			chk[i]&=vis[e[j].to];
	}
	bfs2();
	printf("%d\n",dis[t]==2e9?-1:dis[t]);
}

T3 解方程

哇什么神仙数学题。
看了题解。
mdzz...
可以把式子转化成这种形式a0+x(a1+x(a2+……+x*an))
然后枚举一下x(这貌似是解方程的基本姿势)。把=换成≡。
变成原式≡0(mod MOD)。为了保证正确性多取几个膜数。(牺牲正确性保证效率大法)
比如可以取MOD1=1e9+7;MOD2=1e8+7这对孪生素数。
(虽然我只膜了一次...)
然后效率O(NM)我觉得有点紧张还想省long long省数组什么的…
wa飞了

UPD:还是多膜几次比较清真。

/**************************************************************
    User: ZincSabian
    Language: C++
****************************************************************/
#include<cstdio>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const ll MOD=1e9+9;
const ll Mod=19260817;
inline ll _() {
    ll x=0,f=1; char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())
        if(ch=='-')f=-f;
    for(;ch>='0'&&ch<='9';ch=getchar())
        x=(x*10+ch-'0');
    return x*f;
}
inline void read(ll &a,ll &b,ll&c) {
    a=b=c=0; int f=1; char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())
        if(ch=='-')f=-f;
    for(;ch>='0'&&ch<='9';ch=getchar())
        a=(a*10%mod+ch-'0')%mod,b=(b*10%MOD+ch-'0')%MOD,c=(c*10%Mod+ch-'0')%Mod;
    a=(f>0)?a:-a; b=(f>0)?b:-b; c=(f>0)?c:-c;
}
#define _ _()
int tot;
ll n,m,a[105],b[105],c[105],ans[1000005];
inline bool check(int x) {
    ll sum=0;
    for(int i=n;i>=0;i--)
        sum=(x*sum+a[i])%mod;
    return sum==0;
}
inline bool judge(int x) {
    ll sum=0;
    for(int i=n;i>=0;i--)
        sum=(x*sum+b[i])%MOD;
    return sum==0;
}
inline bool chk(int x) {
    ll sum=0;
    for(int i=n;i>=0;i--)
        sum=(x*sum+c[i])%Mod;
    return sum==0;
}
int main() {
    n=_; m=_;
    for(int i=0;i<=n;i++) read(a[i],b[i],c[i]);
    for(int i=1;i<=m;i++) if(check(i)&&judge(i)&&chk(i)) ans[++tot]=i;
    printf("%d\n",tot);
    for(int i=1;i<=tot;i++) printf("%lld\n",ans[i]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值