本文主要是介绍BUPT2014新生暑假个人排位赛07,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
BOJ 469 暑假作业题
纯模拟,细心耐心,这是我觉得姿势最丑的一次代码
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>using namespace std;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}//-----------------------------------------------------------------------
typedef long long ll;ll num;
ll E,W,Q,B,S,n;bool sovleW(ll n,int have3)//传入 w 之内的数
{if(n==0)return false;int temp=n/1000LL;int have=0,have2=0;if(temp>0){printf("%dQ",temp);have=1;have3=0;}n%=1000LL;temp=n/100LL;if(temp>0){if(have3)putchar('0');printf("%dB",temp);have=0;have2=1;have3=0;}n%=100LL;temp=n/10LL;if(temp>0){if(have||have3)putchar('0');have=0;have2=0;have3=0;printf("%dS",temp);}n%=10LL;temp=n;if(temp>0){if(have||have2||have3)putchar('0');printf("%d",temp);}
}bool sovleE(ll n)
{if(n==0)return false;int temp=n/100000000LL;int have=0,have2=0;if(temp>0){printf("%dE",temp);have=1;}n%=100000000LL;temp=n/10000LL;if(temp>0){sovleW(temp,have);putchar('W');have2=1;}n%=10000LL;sovleW(n,have2||have);
}int main()
{int T;
// freopen("data.txt","r",stdin);read(T);while(T--){read(n);E=n/100000000LL;int have=0,have2=0;if(E>0){sovleE(E);putchar('E');have=1;}n%=100000000LL;W=n/10000;if(W>0){sovleW(W,have);putchar('W');have2=1;}n%=10000;if(n>0){sovleW(n,have2||have);}if(n==0&&!have&&!have2)putchar('0');putchar('\n');}return 0;
}
BOJ 443 最长数链
原意是考察DFS,但是人工总结出了最优解,
第二项为 2 或者 3,其余项为前一项乘 2 。明显地,前一项乘 2 将会构成最长的数列,如果第二项是4的话,肯定比第二项为2的短,其余更大的数类推。
至于 2 和 3 ,则根据所给数关于 2 的 幂的关系
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>using namespace std;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}//-----------------------------------------------------------------------int main()
{int n;while(read(n)){int temp=(log(n/1.0)/log(2.0)+1e-9);int a=log((double)n/2.0)/log(2.0);int b=log((double)n/3.0)/log(2.0);
// cout<<a<<" "<<b<<endl;cout<<" "<<temp<<" "<<log(n/1.0)/log(2.0)<<endl;if(a!=b||fabs((double)temp-log(n/1.0)/log(2.0))<=1e-9){putchar('1');for(int i=2;i<=n;i*=2)printf(" %d",i);putchar('\n');}else if(a==b){putchar('1');for(int i=3;i<=n;i*=2)printf(" %d",i);putchar('\n');}}return 0;
}
BOJ 453 三角形的传说
数学题,可以用找规律代替计算。详见代码,大尧神总结出了一个规范的证明,过段时间再贴上来吧
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#define EPS 1e-10
#define INF 0x3f3f3f3f
#define ll long longusing namespace std;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}
template <class T>
inline void write(T n) {if(n < 0) {putchar('-');n = -n;}int len = 0,data[20];while(n) {data[len++] = n%10;n /= 10;}if(!len) data[len++] = 0;while(len--) putchar(data[len]+48);
}//-----------------------------------------------------------------------int m,q;int main()
{int T,cas=0;for(read(T);cas<T;){read(m),read(q);printf("Case %d: ",++cas);int circle=2*q;if(q*2>m){write(circle+m);}else if(q!=1&&q!=0){write(circle+2*m);}else{write(circle+3*m);}putchar('\n');}return 0;
}
BOJ 454 帮帮小叮当
图论之最短路构图方法:
将所有的传送站与(1,1)点、(n,m)点相连,权值为 两点的曼哈顿距离,所有相邻行的传送站相连,权值为1、
用姿势好的spfa,或者spfa+slf优化,或者更加松弛方向优化
根据松弛方向优化(应该是贪心决策了必然的松弛方向,然后进行类似DP的递推)
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#define EPS 1e-10
#define INF 0x3f3f3f3fusing namespace std;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}//-----------------------------------------------------------------------const int MAXN=10010;
int n,m;
struct Node
{int diss,dise;int x,y;
}c[MAXN];
int dp[MAXN];int dist(int x,int y,int xx,int yy)
{return fabs(x-xx)+fabs(y-yy);
}// 相邻行的传送门int main()
{// freopen("data.txt","r",stdin);while(read(n)&&read(m)&&n&&m){for(int i=1;i<=n;i++){read(c[i].y);c[i].x=i;c[i].diss=dist(c[i].x,c[i].y,1,1);c[i].dise=dist(c[i].x,c[i].y,n,m);}dp[0]=INF;for(int i=1;i<=n;i++)dp[i]=min(dp[i-1]+1,c[i].diss);for(int i=n-1;i>=1;i--)dp[i]=min(dp[i+1]+1,dp[i]);int ans=INF;for(int i=1;i<=n;i++)ans=min(ans,dp[i]+c[i].dise);printf("%d\n",ans);}return 0;
}
姿势稍微好一些的SPFA,代码由大A神提供
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#define eps 1e-9
#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}const int MAXN=10010;
int n,m,Index;
int head[MAXN],next[5*MAXN],node[5*MAXN],value[5*MAXN],path[MAXN],cnt[MAXN];
bool vis[MAXN];
struct cmp
{bool operator ()(const int &a,const int &b) const{return path[a]<path[b] || (path[a]==path[b] && a<b);}
};
void addnode(int a,int b,int v)
{Index++;next[Index]=head[a];node[Index]=b;value[Index]=v;head[a]=Index;
}
int relax(int u, int v, int c)
{if( path[v] > path[u] + c ){path[v] = path[u] + c;return 1;}return 0;
}
int SPFA(int src, int n)
{// 此处用队列实现int i;memset(cnt, 0, sizeof(int)*(n+10)); // 入队次数memset(vis, false, sizeof(bool)*(n+10));for( i=1; i <= n; ++i ) path[i] = INF;path[src] = 0;queue<int> Q;Q.push(src); vis[src] = true; ++cnt[src];while( !Q.empty() ){int u, v;u = Q.front();Q.pop();vis[u] = false;for( i=head[u];i; i=next[i] ){v = node[i];if( 1 == relax(u, v, value[i]) && !vis[v] ){Q.push(v); vis[v] = true;if( (++cnt[v]) > n ) return -1; // cnt[i]为入队列次数,用来判断是否存在负权回路}}}if( path[n] == INF )return -2; // src与n不可达,有些题目可省!!!return path[n]; // 返回src到n的最短距离,根据题意不同而改变
}
int main()
{while(read(n)&&read(m)&&n&&m){Index=0;memset(head,0,sizeof(int)*(n+10));memset(next,0,sizeof(int)*(n+10));int temp;scanf("%d",&temp);addnode(0,1,temp-1);addnode(1,n+1,n-1+m-temp);for(int i=2;i<=n;i++){read(temp);addnode(i-1,i,1);addnode(i,i-1,1);addnode(0,i,i-1+temp-1);addnode(i,n+1,n-i+m-temp);}printf("%d\n",SPFA(0,n+1));}return 0;
}
用SLF优化的SPFA
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#define eps 1e-9
#define INF 0x3f3f3f3fusing namespace std;typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> pll;
typedef complex<ld> point;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;template<class T>
inline bool read(T &n)
{T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}
//---------------------------------------const int MAXN=10010;
int n,m,Index;
struct Edge
{int to,next,v;
}el[MAXN*5];
int head[MAXN],d[MAXN];
bool vis[MAXN];void addedge(int a,int b,int v)
{Index++;el[Index].next=head[a];el[Index].to=b;el[Index].v=v;head[a]=Index;
}void Spfa()
{memset(vis, false, sizeof(bool)*(n+10));d[0]=0;vis[0]=true;deque <int> q;q.push_back(0);while(!q.empty()){int x=q.front();q.pop_front();for(int k=head[x];k!=-1;k=el[k].next){int y=el[k].to;if(d[y]>d[x]+el[k].v){d[y]=d[x]+el[k].v;if(!vis[y]){vis[y]=true;if(!q.empty()){if(d[y]>d[q.front()])q.push_back(y);elseq.push_front(y);}elseq.push_back(y);}}}vis[x]=false;}return ;
}int main()
{while(read(n)&&read(m)&&n&&m){Index=0;memset(head,-1,sizeof(int)*(n+10));memset(d,0x3f,sizeof(int)*(n+10));int temp;read(temp);addedge(0,1,temp-1);addedge(1,n+1,n-1+m-temp);for(int i=2;i<=n;i++){read(temp);addedge(i-1,i,1);addedge(i,i-1,1);addedge(0,i,i-1+temp-1);addedge(i,n+1,n-i+m-temp);}Spfa();printf("%d\n",d[n+1]);}return 0;
}
BOJ 446 大神题
用线段树维护几个数之间的gcd(田神说gcd是加性函数然后用记忆话搜索的容斥原理,计算出答案
容斥原理类似于 m/2+m/3-m/6
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <fstream>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
#define eps 1e-9
#define INF 0x3f3f3f3f
#define MAXN 10005
#define ll long longusing namespace std;
template<class T>
inline bool read(T &n){T x = 0, tmp = 1; char c = getchar();while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();if(c == EOF) return false;if(c == '-') c = getchar(), tmp = -1;while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();n = x*tmp;return true;
}template <class T>
inline void write(T n) {if(n < 0) {putchar('-');n = -n;}int len = 0,data[20];while(n) {data[len++] = n%10;n /= 10;}if(!len) data[len++] = 0;while(len--) putchar(data[len]+48);
}ll prime[]={2,3,5,7,11,13,17,19,23,29,31};
struct node
{int left, right;ll gcd;
}arr[MAXN*6];ll num[MAXN], a[MAXN], c;
ll gcd(ll a, ll b)
{return b==0?a:gcd(b,a%b);
}
void build(int idx, int l, int r)
{arr[idx].left = l, arr[idx].right = r;arr[idx].gcd = 0;if(l == r){arr[idx].gcd = num[l];return;}int mid = (l + r) >> 1;build(idx << 1, l, mid);build(idx << 1 | 1, mid + 1, r);arr[idx].gcd = gcd(arr[idx << 1].gcd , arr[idx << 1 | 1].gcd);
}
ll ans;
bool query(int idx, int l, int r)
{if(arr[idx].right < l||arr[idx].left > r)return false;if(arr[idx].left >= l&&arr[idx].right <= r){ans=gcd(ans,arr[idx].gcd);return true;}query(idx << 1, l, r);query(idx << 1 | 1, l, r);return true;
}void update(int idx, int val, int pos)
{int l = arr[idx].left, r = arr[idx].right;if(l == r){arr[idx].gcd=val;return;}int mid = (l + r) >> 1;if(pos <= mid)update(idx << 1, val, pos);elseupdate(idx << 1 | 1, val, pos);//printf("%I64d(I64d,%I64d)\n",arr[idx].gcd, arr[idx<<1].gcd, arr[idx<<1|1].gcd);arr[idx].gcd = gcd(arr[idx<<1].gcd, arr[idx<<1|1].gcd);
}int fa[1010][10];
inline void Get_fac(int m)
{ int tot=0,temp=m; if(fa[m][0]!=0)return;for(int i=2;i*i<=temp;i++) if(temp%i==0){ fa[m][++tot]=i; while(temp%i==0)temp/=i; } if(temp!=1)fa[m][++tot]=temp; fa[m][0]=tot;
} int sum[1<<11],q;
ll Sum(int m,ll n)
{int i,j;Get_fac(m);sum[0]=1;sum[1]=1;for(i=1;i<=fa[m][0];i++){int k=sum[0];for(j=1;j<=sum[0];j++){sum[++k]=fa[m][i]*sum[j]*-1;}sum[0]=k;}
// for(i=1;i<=sum[0];i++) printf("%d ",sum[i]);printf("\n");ll ret=n;for(i=2;i<=sum[0];i++)ret+=n/sum[i];return ret;
}int main()
{int t, n, q, l, r, m;ll g1;//int c=floor(log(2)/log(2)+eps);while(read(n)){read(m);read(q);for(int i=1;i<=n;i++)read(num[i]);build(1,1,n);
/* for(int i=1;i<2*n;i++)printf("(%d:%I64d[%d,%d]) ",i,arr[i].gcd,arr[i].left,arr[i].right);puts("");*/int cnt=floor(log(n)/log(2)+eps);int o;while(q--){read(o),read(l);if(o==1){read(r);ans=num[l];query(1,l,r);if(ans==1){write(-1);putchar('\n');}else{write(Sum(ans,m)-1);putchar('\n');}}else{read(g1); num[l]=g1;update(1,g1,l);}}}return 0;
}
这篇关于BUPT2014新生暑假个人排位赛07的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!