以下我的简单题解,网上题解很多...
A:https://codeforces.com/contest/1110/problem/A
以下性质:
1:偶*偶,奇*偶,为偶数,奇*奇为奇数。
2:x如果为奇数,x^n也是奇数,偶数同理。
就可以轻松切了这题。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<climits>
using namespace std;
int main (){
int b,k,a[100005];
cin>>b>>k;
for(int i=1;i<=k;i++)
scanf("%d",&a[i]);
int re=0;
for(int i=1;i<k;i++){
int x=b%2,y=a[i]%2;
if(x%2==0||y%2==0) re=re+0;
else re=(re+1)%2;
}
if(a[k]%2) re=(re+1)%2;
if(re%2) cout<<"odd";
else cout<<"even";
return 0;
}
B:https://codeforces.com/problemset/problem/1076/C
由 和,可得:
然后就是高中数学题
时无解,否则一组解是和
以下lhm代码(:D)
#include<iostream>
using namespace std;
int main(){
double d;
int t;
scanf("%d", &t);
while (t--)
{
scanf("%lf", &d);
if (d*d < 4 * d)
printf("N\n");
else
{
double tt = d*d - 4.0 * d;
double an = d + (double)sqrt(tt);
an = an / (double)2;
printf("Y %.9lf %.9lf\n", an, d - an);
}
}
return 0;
}
此题也可根据函数单调性二分....
以下cb代码
#include<stdio.h>
#include<queue>
#include<cstring>
using namespace std;
const int maxn=100000+30;
#define dou double
dou bSearch(dou d)
{
dou mid,left=0,right=d;
if(!d) return 0;
while(left<=right)
{
mid=(left+right)/2;
if(d-mid>=d/mid) right=mid-0.0000000001;
else left=mid+0.0000000001;
}
return left;
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
dou d;
scanf("%lf",&d);
if(d<4&&d>0) puts("N");
else if(d==4) printf("Y 2.000000000 2.000000000\n");
else{
dou temp=bSearch(d);
printf("");
printf("Y %.9lf %.9lf\n",d-temp,temp);
}
}
return 0;
}
C:http://acm.hdu.edu.cn/showproblem.php?pid=1042
大数模拟,注意细节。
/* Author : Rshs
* Data : 2019-09-09-18.23
*/
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
const double pai = acos(-1);
const LL mod = 1e9+7;
const int MX = 1e6+5;
struct no{
int le; //长度
int a[MX]; //大数
}n;
void mul(int x){ //求n*x,封装到n里
reverse(n.a,n.a+n.le); //先反过来,好处理
for(int i=0;i<n.le;i++) n.a[i]*=x;//先乘,
for(int i=0;i<n.le;i++){ //再统一进位
int yu=n.a[i]%10;
int jin=n.a[i]/10;
n.a[i+1]+=jin;
n.a[i]=yu;
}
if(n.a[n.le]) n.le++; //le处有进数
while(n.a[n.le-1]>=10){//不断处理le处的进数
int yu=n.a[n.le-1]%10;
int jin=n.a[n.le-1]/10;
n.a[n.le]+=jin;
n.a[n.le-1]=yu;
n.le++;
}
reverse(n.a,n.a+n.le); //最后再反过来
}
int main(){
int nn;
int last=0;//记录上次长度,用于清空
while(cin>>nn){
//初始化
for(int i=0;i<=last;i++)n.a[i]=0;
n.le=1;n.a[0]=1;
for(int i=1;i<=nn;i++)mul(i);
for(int i=0;i<n.le;i++) cout<<n.a[i];
puts("");
last=n.le;
}
return 0;
}
zm精简代码 (:D)
#include<cstdio>
int a[10017];
int main(){
int i,j,jin,n;
while(~scanf("%d",&n)){
for(int i=0;i<10000;++i)a[i]=0;
jin=0;a[0]=1;
for(i=1;i<=n;i++){
for(j=0;j<=jin;j++){
a[j]=a[j]*i;
if(j>0&&a[j-1]>10000){
a[j]=a[j]+a[j-1]/10000;
a[j-1]=a[j-1]%10000;
}
if(a[jin]>=10000) jin++;
}
}
printf("%d",a[jin]);
for(i=jin-1;i>=0;i--) printf("%04d",a[i]); printf("\n");
}
}
D:http://poj.org/problem?id=3278
从农夫的起点bfs即可,或者记忆化dfs
以下wqq代码(:D)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
const int inf=0x3f3f3f3f;
const int maxn=1e5+10;
int n,b,k,ans=0;
bool vis[maxn];
int bfs(){
queue<P> q;
q.push(make_pair(n,0));
while(!q.empty()){
P now= q.front();q.pop();
if(now.first==k){
return now.second;
}
if(now.first+1<=100000&&!vis[now.first+1]){//向右
vis[now.first+1]=1;q.push(make_pair(now.first+1,now.second+1));
}
if(now.first-1>=0&&!vis[now.first-1]){//向左
vis[now.first-1]=1;q.push(make_pair(now.first-1,now.second+1));
}
if(now.first*2<=100000&&!vis[now.first*2]){ //向两倍的地方走
vis[now.first*2]=1;q.push(make_pair(now.first*2,now.second+1));
}
}
return 0;
}
int main()
{
scanf("%d%d",&n,&k);
if(n>=k)ans=n-k;
else ans=bfs();
printf("%d\n",ans);
return 0;
}
E: http://acm.hdu.edu.cn/showproblem.php?pid=1213
并查集维护一下,最后统计维护了几颗树就行。
以下zm代码(:D)
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int pr[1017];
int f(int i){
return i==pr[i]?i:pr[i]=f(pr[i]);
}
void u(int x,int y){
pr[f(x)]=f(y);
}
int main(){
int T;scanf("%d",&T);
while(T--){
int ans=0,n,m,x,y;
scanf("%d%d",&n,&m);
for(int i=0;i<=n;++i) pr[i]=i;
for(int i=0;i<m;++i){
scanf("%d%d",&x,&y);
if(f(x)!=f(y)) u(x,y);
}
for(int i=1;i<=n;++i){ //求树的棵数
if(pr[i]==i) ans++;
}
printf("%d\n",ans);
}
return 0;
}
F:http://acm.hdu.edu.cn/showproblem.php?pid=2066
将草儿家和草儿家旁边的城市连一条边,边权为0,跑一遍单源最短路,答案就是min(d[想去的地方])。
以下zm代码(:D)
#include<cstdio>
#include<queue>
#include<set>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Mn=1e3+17;
set<int> d; //存想去的城市
struct S{ //优先队列节点
int v,l;
S(){}
S(int xx,int yy):v(xx),l(yy){}
bool operator <(const S &r)const{
return l>r.l;
}
};
struct Edge{ //图节点
int v,l;
Edge(int xx,int yy):v(xx),l(yy){}
};
int n,m,c;
bool vis[Mn];
int dis[Mn];
vector<Edge> e[Mn];
int dij(int s){
int minn=INF;
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;++i) dis[i]=INF;dis[s]=0;
priority_queue<S> q;while(!q.empty()) q.pop();
q.push(S(s,0));
S tmp;
while(!q.empty()){
tmp=q.top();q.pop();
int u=tmp.v;
if(vis[u]) continue;
vis[u]=true;
for(int i=0;i<(int)e[u].size();++i){
int v=e[tmp.v][i].v,c=e[tmp.v][i].l;
if(!vis[v]&&dis[v]>dis[u]+c){
dis[v]=dis[u]+c;
if(dis[v]<minn&&d.find(v)!=d.end()){ //更新答案
// printf("v=%d,dis=%d\n",v,dis[v]);
minn=dis[v];
}
q.push(S(v,dis[v]));
}
}
}
return minn;
}
int team[Mn];
int main(){
int t,near,D,u,v,len;
while(~scanf("%d%d%d",&t,&near,&D)){
for(int i=0;i<=n;++i) e[i].clear();
d.clear();
for(int i=0;i<t;++i){
scanf("%d%d%d",&u,&v,&len);
e[u].push_back(Edge(v,len));
e[v].push_back(Edge(u,len));
n=max(max(n,u),v);
}
for(int i=0;i<near;++i){ //草儿家和草儿家旁边的城市连边
int ne;scanf("%d",&ne);
e[0].push_back(Edge(ne,0));
}
for(int i=0;i<D;++i){
int want;scanf("%d",&want);
d.insert(want);
}
printf("%d\n",dij(0));
}
return 0;
}
G:https://codeforces.com/contest/237/problem/C
先筛素数,然后统计前缀素数个数。
因为L变大,要符合题意的xi变少,且前缀区间变大,所以满足单调性,直接二分L。
/* Author : Rshs
* Data : 2019-09-09-19.50
*/
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
const double pai = acos(-1);
const LL mod = 1e9+7;
const int MX = 1e6+5;
int pi[MX],pa[MX];int a,b,k;
void pppp(){
pi[1]=1;
for(int i=2;i<MX;i++) {
if(pi[i])continue;
for(int j=i*2;j<MX;j=j+i) pi[j]=1;
}
for(int i=1;i<MX;i++) pa[i]=pa[i-1]+(pi[i]==0);
}
bool check(int l){
for(int i=a;i<=b-l+1;i++)
if(pa[i+l-1]-pa[i-1]<k) return 0;
return 1;
}
void Main(int avg){
cin>>a>>b>>k;int ans=-1,l=1,r=b-a+1;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
cout<<ans<<'\n';
}
int main(){
pppp();
int cas=1;for(int i=1;i<=cas;i++)Main(i);
return 0;
}
H:https://codeforces.com/problemset/problem/1118/F1
先将树从一个节点拎起来,dfs每一个节点作为根的子树。
如果子树包含所有的蓝色节点且没有红色节点,或者包含所有红且没有蓝就可以割出来这个子树作为一个答案。
统计满足上述的子树个数即可。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define mod 1000000007
#define N 300005
/***************************************************************************************************************************************************************************************************/
int n,red,bule,a[N];
vector<int> v[N];
int dp[N][3];
int dfs(int root,int per,int c){
if(a[root]==c) dp[root][c]++;
if(v[root].size()==1) return dp[root][c];
for(int i=0;i<v[root].size();i++){
if(v[root][i]==per) continue;
dp[root][c]+=dfs(v[root][i],root,c);
}
return dp[root][c];
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]==1) red++;
if(a[i]==2) bule++;
}
for(int i=1;i<=n-1;i++){
int vv,uu;
scanf("%d%d",&vv,&uu);
v[vv].push_back(uu);
v[uu].push_back(vv);
}
if(n==2) {
cout<<1;
return 0;
}
for(int i=1;i<=n;i++){
if(v[i].size()>1){
dfs(i,-1,1);
dfs(i,-1,2);
break;
}
}
int ans=0;
for(int i=1;i<=n;i++){
if(dp[i][1]==red&&dp[i][2]==0) ans++;
if(dp[i][1]==0&&dp[i][2]==bule) ans++;
}
cout<<ans;
return 0;
}
I:
定义dp[i][j][k],
k==0时,表示到(i,j)时,2累计有几个。
k==1时,表示到(i,j)时,5累计有几个。
答案就是min(dp[n][n][0],dp[n][n][1])。
最后用一个数组记录一下前驱,就可以反向输出路径。
注意输入有0,小心死循环,而且答案为0
/* Author : Rshs
* Data : 2019-09-09-20.50
*/
#include<bits/stdc++.h>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define MP make_pair
#define PII pair<int,int>
#define SZ(a) (int)a.size()
const double pai = acos(-1);
const LL mod = 1e9+7;
const int MX = 1e6+5;
int mp[1005][1005];
int dp[1005][1005][2];
int pa[1005][1005][2];
char go[2]={'D','R'};
vector<char>v;
void Main(int avg){
int n;cin>>n;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&mp[i][j]);
for(int i=0;i<=n;i++)for(int j=0;j<2;j++)dp[i][0][j]=INT_MAX,dp[0][i][j]=INT_MAX;
int c=0,d=0,e=mp[1][1],f=mp[1][1];
while(e%2==0)e/=2,c++;
while(f%5==0)f/=5,d++;
dp[1][1][0]=c;dp[1][1][1]=d;
int ans=INT_MAX;PII an;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==1&&j==1)continue;
int c=0,d=0,e=mp[i][j],f=mp[i][j];
if(e!=0){
while(e%2==0)e/=2,c++;
while(f%5==0)f/=5,d++;
}
else ans=1,an=MP(j,i);
if(dp[i-1][j][0]>dp[i][j-1][0])dp[i][j][0]=dp[i][j-1][0]+c,pa[i][j][0]=1;
else dp[i][j][0]=dp[i-1][j][0]+c,pa[i][j][0]=0;
if(dp[i-1][j][1]>dp[i][j-1][1])dp[i][j][1]=dp[i][j-1][1]+d,pa[i][j][1]=1;
else dp[i][j][1]=dp[i-1][j][1]+d,pa[i][j][1]=0;
}
}
int x=n,y=n,z;
if(dp[n][n][0]<dp[n][n][1])z=0;
else z=1;
int now=min(dp[n][n][0],dp[n][n][1]);
if(now>ans){ //有0
cout<<ans<<endl;
for(int i=1;i<an.FI;i++) cout<<'R';
for(int i=1;i<an.SE;i++) cout<<'D';
for(int i=1;i<=n-an.FI;i++) cout<<'R';
for(int i=1;i<=n-an.SE;i++) cout<<'D';
return ;
}
cout<<now<<endl;
for(int i=1;i<=2*n-2;i++){
v.push_back(go[pa[x][y][z]]);
if(pa[x][y][z]==0) x--;
else y--;
}
reverse(v.begin(),v.end());
for(auto i:v)cout<<i;
}
int main(){
int cas=1;for(int i=1;i<=cas;i++)Main(i);
return 0;
}