只要单纯的判断一下前后的乘积就好了, 因为不是很想处理倍数的关系, 所以我这里是用 string去处理。
代码:
1 #include2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c))10 const int INF = 0x3f3f3f3f;11 const LL mod = 1e9+7;12 typedef pair pll;13 char str[10];14 int n, k;15 bool add(){16 for(int i = n - 1; i >= 1; i--){17 if((str[i-1]-'0')*(str[i]-'0'+1) <= k && str[i]-'0'+1 <= k) {str[i] = str[i] + 1;return true;}18 else str[i] = '0';19 }20 if(str[0]-'0'+1 <= k) {str[0] = str[0]+1; return true;}21 return false;22 }23 int main(){24 scanf("%d%d",&n,&k);25 str[0] = '1';26 for(int i = 1; i < n; i++) str[i] = '0';27 str[n] = '\0';28 while(1){29 printf("%s\n", str);30 if(!add()) break;31 }32 return 0;33 }
求最小的D,D=|Ai-Bj|+|Bj-Ck|+|Ck-Ai|
假设A > B > C , D = 2(A - C)。 假设 A > C > B , D = 2(A - B)。
我们可以发现 D 就等于最大的那个数减去最小的那个数 再乘以2, 所以我们直接去对A,B,C的大小关系进行全排列, 然后对于每个a[i], 找到大于等于a[j],且最小的b[j], 再找到大于等于b[j]的最小的c[k], 求出每一个成立的 (c[k]-a[i])并取其中最小的那个就好了。
代码:
1 #include2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c))10 const int INF = 0x3f3f3f3f;11 const LL mod = 1e9+7;12 typedef pair pll;13 const int N = 100010;14 int A[N], B[N], C[N];15 int ans = 1e9;16 void solve(int a[], int n, int b[], int m, int c[], int l){17 for(int i = 1; i <= n; i++){18 int p1 = lower_bound(b+1,b+1+m,a[i]) - b;19 if(p1 == m+1) return;20 int p2 = lower_bound(c+1,c+1+l,b[p1]) - c;21 if(p2 == l+1) return;22 ans = min(ans, 2*(c[p2]-a[i]));23 }24 }25 int main(){26 int n, m, l;27 scanf("%d%d%d",&n,&m,&l);28 for(int i = 1; i <= n; i++)29 scanf("%d",&A[i]);30 for(int i = 1; i <= m; i++)31 scanf("%d",&B[i]);32 for(int i = 1; i <= l; i++)33 scanf("%d",&C[i]);34 sort(A+1, A+1+n);35 A[n+1] = 1e9;36 sort(B+1, B+1+m);37 B[m+1] = 1e9;38 sort(C+1, C+1+l);39 C[l+1] = 1e9;40 solve(A,n,B,m,C,l);41 solve(A,n,C,l,B,m);42 solve(B,m,A,n,C,l);43 solve(B,m,C,l,A,n);44 solve(C,l,A,n,B,m);45 solve(C,l,B,m,A,n);46 printf("%d", ans);47 return 0;48 }
代码:
1 #include2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c))10 const int INF = 0x3f3f3f3f;11 const LL mod = 1e9+7;12 typedef pair pll;13 14 int main(){15 int n, last, t;16 while(~scanf("%d",&n), n != -1){17 for(int i = 1; i <= n; i++){18 scanf("%d", &t);19 if(i == 1){printf("%d",t); last = t;}20 if(last != t){21 printf(" %d", t);22 last = t;23 }24 }25 printf("\n");26 }27 return 0;28 }
求的是查询的时候输出X同学与Y同学之间的分数差距(不清楚输出-1),莫非用最短路跑出所有点之间的距离? N = 1e5。 就算不T数组也开不下。
后来发现可以跑出2个人之间的关系,并且建立能联通的人之间的相对关系就好了, 将第一个人的分数设为0, 然后通过边的关系处理出别人的分数。
然后每次询问的时候,判断X与Y是不是同一次访问的,如果是输出分数差,如果不是就输出-1。
代码:
1 #include2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c))10 const int INF = 0x3f3f3f3f;11 const LL mod = 1e9+7;12 typedef pair pll;13 const int N = 100010;14 int vis[N], val[N], head[N];15 struct Node{16 int to;17 int ct;18 int nt;19 }e[N<<1];20 int tot = 0;21 void add(int u, int v, int w){22 e[tot].to = v;23 e[tot].ct = w;24 e[tot].nt = head[u];25 head[u] = tot++;26 }27 void dfs(int u, int cnt){28 vis[u] = cnt;29 for(int i = head[u]; ~i; i = e[i].nt){30 if(!vis[e[i].to]){31 val[e[i].to] = val[u]-e[i].ct;32 dfs(e[i].to,cnt);33 }34 }35 }36 int main(){37 memset(head, -1, sizeof(head));38 int n, m, q;39 int u, v, w;40 scanf("%d%d%d", &n, &m, &q);41 for(int i = 1; i <= m; i++){42 scanf("%d%d%d",&u,&v,&w);43 add(u,v,w);44 add(v,u,-w);45 }46 int cnt = 1;47 for(int i = 1; i <= n; i++){48 if(!vis[i]){49 val[i] = 0;50 dfs(i,cnt++);51 }52 }53 for(int i = 1; i <= q; i++){54 scanf("%d%d",&u,&v);55 if(vis[u] != vis[v]) printf("-1\n");56 else printf("%d\n",val[u]-val[v]);57 }58 return 0;59 }