题目来自ICPC2017 Hua-Lien
有一串序列,题目要求最多有一组连续两个数字之差的绝对值大于d,问输入的序列是否满足这个条件
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main() 5 { 6 int n,d,a[10005]; 7 while(scanf("%d",&n)!=EOF) 8 { 9 if(n==0) break; 10 scanf("%d",&d); 11 int d_count=0; 12 int pos[1005],cnt=0; 13 for(int i=1;i<=n;i++) 14 { 15 scanf("%d",&a[i]); 16 if(i==1) continue; 17 if(abs(a[i]-a[i-1])>d) d_count++,pos[cnt++]=i; //统计不满足条件的个数 18 } 19 if(n==1||n==2) //特判n==1和n==2的情况 20 { 21 printf("Y\n"); 22 continue; 23 } 24 if(d_count==0) printf("Y\n"); //都满足的情况 25 else if(d_count>=3) printf("N\n"); //一定不满足 26 else if(d_count==1) 27 { 28 if(pos[0]==2||pos[0]==n) //两端的情况 29 printf("Y\n"); 30 else 31 { 32 if(abs(a[pos[0]]-a[pos[0]-1])>2*d&&abs(a[pos[0]-1]-a[pos[0]+1])>2*d) //要看连续的四个数 33 printf("N\n"); 34 else 35 printf("Y\n"); 36 } 37 } 38 else 39 { 40 if(pos[1]-pos[0]!=1) //一定不满足 41 printf("N\n"); 42 else 43 { 44 if(abs(a[pos[0]-1]-a[pos[1]])>2*d)//看连续的三个数 45 printf("N\n"); 46 else 47 printf("Y\n"); 48 } 49 } 50 51 } 52 return 0; 53 }
直接按题目模拟
1 #include<bits/stdc++.h> 2 using namespace std; 3 int c[350][350]; 4 int main() 5 { 6 int t,n; 7 scanf("%d",&t); 8 while(t--) 9 { 10 scanf("%d",&n); 11 int m=(n-1)*n/2; 12 int x,y,z; 13 memset(c,0,sizeof(c)); 14 while(m--) 15 { 16 scanf("%d%d%d",&x,&y,&z); 17 c[x][y]=z; 18 c[y][x]=z; 19 } 20 int ans=-1; 21 for(int i=1;i<=n;i++) 22 { 23 for(int j=1;j<=n;j++) 24 { 25 for(int k=1;k<=n;k++) 26 { 27 if(i!=j&&j!=k&&i!=k) 28 ans=max(ans,c[i][j]+c[j][k]+c[i][k]); 29 } 30 } 31 } 32 printf("%d\n",ans); 33 } 34 return 0; 35 }
求C(n,k)的d进制(1<d<10)
直接用java写
1 import java.util.*; 2 import java.math.BigInteger; 3 public class Main { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 Scanner cin = new Scanner(System.in); 8 int t = cin.nextInt(); 9 BigInteger ans,tmp,p; 10 int n,k,d; 11 String str; 12 while (t-- != 0) { 13 tmp=BigInteger.valueOf(1); 14 ans=BigInteger.valueOf(1); 15 n=cin.nextInt(); 16 k=cin.nextInt(); 17 d=cin.nextInt(); 18 if(k==0||k==n) 19 { 20 ans=BigInteger.valueOf(1); 21 } 22 else if(k==1) 23 { 24 ans=BigInteger.valueOf(n); 25 } 26 else 27 { 28 for(int i=n;i>=n-k+1;i--) 29 { 30 p=BigInteger.valueOf(i); 31 ans=ans.multiply(p); 32 } 33 for(int i=1;i<=k;i++) { 34 p=BigInteger.valueOf(i); 35 tmp=tmp.multiply(p); 36 37 } 38 ans=ans.divide(tmp); 39 40 } 41 str=ans.toString(d); 42 System.out.println(str); 43 44 } 45 } 46 47 }
直接Floyd
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int INF=1e7; 5 int dis[220][220]; 6 int ans[220]; 7 void init(int n) 8 { 9 for(int i=0; i<n; i++){ 10 for(int j=0; j<n; j++) 11 dis[i][j]=INF; 12 dis[i][i]=0; 13 } 14 memset(ans,0,sizeof(ans)); 15 } 16 int main() 17 { 18 int n,m; 19 while(1) 20 { 21 scanf("%d",&n); 22 if(n==0) 23 break; 24 init(n); 25 scanf("%d",&m); 26 int a,b; 27 for(int i=0; i<m; i++) 28 { 29 scanf("%d %d",&a,&b); 30 dis[a][b]=dis[b][a]=1; 31 } 32 for(int k=0; k<n; k++) 33 for(int i=0; i<n; i++) 34 for(int j=0; j<n; j++) 35 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 36 37 for(int i=0; i<n; i++) 38 for(int j=0; j<n; j++) 39 if(dis[i][j]!=INF) 40 ans[dis[i][j]]++; 41 42 for(int i=1;i<=n;i++) 43 if(ans[i]) 44 printf("%d %d\n",i,ans[i]); 45 } 46 return 0; 47 }
1 #include<bits/stdc++.h> 2 using namespace std; 3 int t; 4 typedef long long ll; 5 ll n,p[100005],c[100005],m,tmp; 6 void fun() 7 { 8 m=0; 9 tmp=1; 10 for(ll i=2;i<=sqrt(n);i++) //分解质因数,并求出每个质因数出现的次数 11 { 12 if(n%i==0) 13 { 14 p[++m]=i,c[m]=0; 15 while(n%i==0) n/=i,c[m]++; 16 } 17 } 18 if(n>1) 19 p[++m]=n,c[m]=1; 20 for(int i=1;i<=m;i++) //算出所有的乘积 21 tmp*=(c[i]+1); 22 } 23 int main() 24 { 25 scanf("%d",&t); 26 while(t--) 27 { 28 scanf("%lld",&n); 29 fun(); 30 ll ans=0; 31 for(int i=1;i<=m;i++) //求每种状态的和 32 ans+=(tmp/(c[i]+1)*c[i]); 33 printf("%lld\n",ans); 34 } 35 return 0; 36 }
求二分图最小点覆盖包含的点数。根据定理其等于二分图最大匹配包含的边数
可以当作一个模板了
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 struct node //定义结构体 5 { 6 int to,next; 7 }edge[150]; 8 int head[150],tot,match[150]; 9 bool visit[150]; 10 void init() //初始化 11 { 12 memset(head,-1,sizeof(head)); 13 memset(match,-1,sizeof(match)); 14 tot=0; 15 } 16 void addedge(int u,int v) //邻接链表存边 17 { 18 edge[tot].to=v; 19 edge[tot].next=head[u]; 20 head[u]=tot++; 21 } 22 bool dfs(int u) //匈牙利算法 23 { 24 for(int i=head[u];i!=-1;i=edge[i].next) 25 { 26 int v=edge[i].to; 27 if(!visit[v]) 28 { 29 visit[v]=1; 30 if(match[v]==-1||dfs(match[v])) 31 { 32 match[v]=u; 33 return true; 34 } 35 } 36 } 37 return false; 38 } 39 int main() 40 { 41 //freopen("in.txt","r",stdin); 42 int n,m,e; 43 while(1) 44 { 45 init(); 46 int ans=0; 47 scanf("%d",&n); 48 if(n==0) 49 break; 50 scanf("%d",&m); 51 scanf("%d",&e); 52 int a,b; 53 for(int i=1;i<=e;i++) 54 { 55 scanf("%d %d",&a,&b); 56 addedge(a,b); 57 } 58 for(int i=0;i<n;i++) //n对应的是左边的点数目 59 { 60 memset(visit,0,sizeof(visit)); 61 if(dfs(i)) 62 ans++; 63 } 64 printf("%d\n",ans); 65 } 66 return 0; 67 }
暴搜
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 int mp[30][30],n; 5 int color[30]; 6 bool check(int x) 7 { 8 for(int i=0; i<x; i++) 9 { 10 if(mp[i][x]==1&&color[x]==color[i]) 11 { 12 return false; 13 } 14 } 15 return true; 16 } 17 bool dfs(int x) 18 { 19 if(!check(x)) 20 { 21 return false; 22 } 23 if(x==n-1) 24 return true; 25 for(int i=0;i<3;i++) 26 { 27 color[x+1]=i; 28 if(dfs(x+1)) 29 { 30 return true; 31 } 32 } 33 return false; 34 } 35 int main() 36 { 37 //freopen("in.txt","r",stdin); 38 int t,m,a,b; 39 scanf("%d",&t); 40 while(t--) 41 { 42 scanf("%d",&n); 43 scanf("%d",&m); 44 for(int i=1; i<=m; i++) 45 { 46 scanf("%d %d",&a,&b); 47 mp[a][b]=1; 48 mp[b][a]=1; 49 } 50 if(dfs(0)) 51 { 52 printf("Y\n"); 53 } 54 else 55 { 56 printf("N\n"); 57 } 58 memset(mp,0,sizeof(mp)); 59 } 60 return 0; 61 }
L题:Finding the Bases
参考https://www.cnblogs.com/albert-biu/p/9544124.html
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int maxn=1e4+5; 5 char s[maxn]; 6 int n,nxt[maxn],dp[maxn]; 7 void getNext(char a[],int len) 8 { 9 for(int i=2,j=0;i<=len;i++) 10 { 11 while(j>0&&a[i]!=a[j+1]) j=nxt[j]; 12 if(a[i]==a[j+1]) j++; 13 nxt[i]=j; 14 } 15 } 16 int main() 17 { 18 int t; 19 scanf("%d",&t); 20 while(t--) 21 { 22 scanf("%s",s+1); 23 n=strlen(s+1); 24 for(int i=1;i<=n;i++) dp[i]=i; 25 for(int i=1;i<=n;i++) 26 { 27 getNext(s+i-1,n-i+1); 28 for(int j=i;j<=n;j++) 29 { 30 int tmp=j-i+1; 31 if(tmp%(tmp-nxt[tmp])==0) 32 dp[j]=min(dp[j],dp[i-1]+tmp-nxt[tmp]); 33 } 34 } 35 printf("%d\n",dp[n]); 36 } 37 return 0; 38 }